Skip to content
All guides

Connect your Base44 form.

Simplest

Ask your agent

  1. 1

    Open your project and paste this into the chat: “Use Ellieforms: ellieforms.com/agent”.

  2. 2

    Your agent shows a sign-in link and a short code. Open the link, sign in with Google or your email, and check the code matches.

  3. 3

    Your agent connects the form, builds the thank-you message, and sends a test. Look for the [TEST] email from Ellieforms.

Your agent keeps your design. On the Free plan, a small “Sent with Ellieforms” link appears under your form.

For developers

Set it up yourself

The same connection by hand, in about ten minutes. The result is identical to what an agent builds.

1. Create the form in Ellieforms

  1. Sign in at app.ellieforms.com with Google or your email.
  2. Open Forms → Add website. Type the site's web address, so messages from it are trusted straight away.
  3. Press + Form, name it (“Contact form”), then open Code.
  4. Copy your form ID (it starts with frm_) and your badge link. In the code below, replace frm_YOUR_FORM_ID and YOUR_BADGE_LINK with them.

2. Add the code to your Base44 project

Base44 projects use React, so this is the React code. Paste it into your editor, or hand it to the chat to apply exactly.

  1. Add the script tag once, inside <head> of index.html.
  2. Use the component below, or give your own form the same attributes and submit handler. Controlled inputs are fine: every field just needs a name.
index.html
<script src="https://in.ellieforms.com/v1/f.js" defer></script>
src/ContactForm.tsx
import { useState } from "react";

export function ContactForm() {
const [status, setStatus] = useState<"idle" | "sending" | "sent" | "error">("idle");

if (status === "sent") return <p role="status">Thanks! We got your message.</p>;

return (
<form
data-ellieforms="frm_YOUR_FORM_ID"
data-ellieforms-mode="call"
action="https://in.ellieforms.com/f/frm_YOUR_FORM_ID"
method="POST"
acceptCharset="UTF-8"
onSubmit={async (event) => {
event.preventDefault();
const form = event.currentTarget;
if (!window.ellieforms) return form.submit(); // script blocked: the plain post still delivers
setStatus("sending");
setStatus((await window.ellieforms.send(form)) ? "sent" : "error");
}}
>
<label>Name <input name="name" autoComplete="name" required /></label>
<label>Email <input type="email" name="email" autoComplete="email" required /></label>
<label>Message <textarea name="message" required /></label>
{/* Bot trap: keep it hidden and empty */}
<input type="text" name="_fh_hp" tabIndex={-1} autoComplete="off" aria-hidden="true" style={{ position: "absolute", left: -9999 }} />
<button type="submit" disabled={status === "sending"}>{status === "sending" ? "Sending…" : "Send"}</button>
{status === "error" && <p role="alert">Sorry, that didn't send. Please try again.</p>}
<a href="YOUR_BADGE_LINK">Sent with Ellieforms</a>
</form>
);
}

3. Test, then go live

  1. Publish your site, open the page and send one message through the form.
  2. It appears in your Ellieforms inbox, and Ellieforms learns the form's fields from it.
  3. In Forms, press Go live. That locks in the fields, so Ellieforms notices if the form changes later.

Free sends one daily summary of real messages; Pro and Team alert you instantly.

Advanced

Everything the code above relies on, for adapting it to your own setup.

What goes on the form

Attribute or fieldRequiredWhy
data-ellieforms="frm_YOUR_FORM_ID"YesTells the script which form this is.
action="https://in.ellieforms.com/f/frm_YOUR_FORM_ID", method="POST"YesThe fallback: if JavaScript fails, the browser still posts the message there.
accept-charset="UTF-8"RecommendedKeeps every language intact in the fallback post.
name on every fieldYesFields without a name are not sent. Repeated names (checkboxes) arrive joined with commas.
Hidden _fh_hp fieldYesA bot trap. People never see it; bots fill it in. Keep it off-screen exactly as shown.
data-ellieforms-mode="call"Only with your own handlerThe script stops handling submit, and your code calls ellieforms.send(form).

The script

Load https://in.ellieforms.com/v1/f.js exactly as shown, once per page, with defer. Don't bundle it, copy it, or add an integrity attribute: fixes reach every site from one place, and v1 never changes in a breaking way. It sets no cookies and makes no third-party requests. On load it solves an invisible bot check for each form, so sending is instant when the visitor clicks.

You useWhat you get
ellieforms:sent eventFired on the form after a successful send; it bubbles. event.detail is { ok: true, status, id }.
ellieforms:error eventFired when sending failed. detail is { ok: false, status }, with network: true when the visitor is offline. In automatic mode the script then falls back to the plain post, so the message still arrives.
await window.ellieforms.send(form)Call mode. Sends the HTMLFormElement you pass (never a component or data object), retries twice, fires the same events and returns true or false.

Forms added later (client-side navigation, htmx swaps, modals) work without extra code: the script listens on the whole page.

TypeScript

Add this file anywhere your tsconfig includes, so window.ellieforms and the events are typed:

src/ellieforms.d.ts
// ellieforms.d.ts: types for the hosted script
export {};

declare global {
interface Window {
ellieforms?: { version: string; send(form: HTMLFormElement): Promise<boolean> };
}
interface DocumentEventMap {
"ellieforms:sent": CustomEvent<{ ok: true; status: number; id?: string }>;
"ellieforms:error": CustomEvent<{ ok: false; status: number; network?: boolean }>;
}
}

Limits and changes

  • Up to 100 fields, 10,000 characters per field and 32 KB per message. File uploads are not sent.
  • The visitor's email address (usually a field named email) becomes the Reply-To of your alert, so you can answer straight from your inbox.
  • Changed the form's fields after going live? Messages still arrive, with a note asking you to confirm the new version. To relearn on purpose: Forms → Relearn fields, send one message, then Go live.
  • Visitors without JavaScript return to your home page after sending, or to your own thank-you page: Forms → Settings.
  • Want Cloudflare Turnstile as well? Add your own keys under Forms → Advanced and put the Turnstile widget inside the form; the script sends its answer along.

Webhooks and the API

Send messages to Zapier, Make, n8n or your own server, or script the setup: see the developer docs.