Connect your Webflow form.
Simplest
Ask your agent
- 1
Ask any AI agent (ChatGPT, Claude) to follow ellieforms.com/agent and connect your Webflow form. It signs you in and gives you the code.
- 2
In Webflow: select your form block and add the two custom attributes it gives you (data-ellieforms and the form action).
- 3
Site Settings → Custom Code → Footer: paste the footer code your agent gave you. Webflow's own success and error messages keep working.
- 4
Publish, then send a test from your live site.
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
- Sign in at app.ellieforms.com with Google or your email.
- Open Forms → Add website. Type the site's web address, so messages from it are trusted straight away.
- Press + Form, name it (“Contact form”), then open Code.
- Copy your form ID (it starts with
frm_) and your badge link. In the code below, replacefrm_YOUR_FORM_IDandYOUR_BADGE_LINKwith them.
2. Add the code to your Webflow site
- Select the form inside your Form Block. In its settings, set Action to https://in.ellieforms.com/f/frm_YOUR_FORM_ID and Method to POST.
- Still in its settings, add a custom attribute: name data-ellieforms, value frm_YOUR_FORM_ID.
- Inside the form, add a Code Embed element with the bot trap below.
- Site Settings → Custom Code → Footer code: paste the script below. It shows Webflow's own success and error blocks. Publish.
<input type="text" name="_fh_hp" tabindex="-1" autocomplete="off" aria-hidden="true" style="position:absolute;left:-9999px"><script src="https://in.ellieforms.com/v1/f.js" defer></script>
<script>
// Show Webflow's own success and error blocks.
document.addEventListener("ellieforms:sent", (event) => {
event.target.style.display = "none";
event.target.closest(".w-form").querySelector(".w-form-done").style.display = "block";
});
document.addEventListener("ellieforms:error", (event) => {
event.target.closest(".w-form").querySelector(".w-form-fail").style.display = "block";
});
</script>Add the badge as a normal Webflow link below the form, pointing to your badge link.
3. Test, then go live
- Publish your site, open the page and send one message through the form.
- It appears in your Ellieforms inbox, and Ellieforms learns the form's fields from it.
- 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 field | Required | Why |
|---|---|---|
data-ellieforms="frm_YOUR_FORM_ID" | Yes | Tells the script which form this is. |
action="https://in.ellieforms.com/f/frm_YOUR_FORM_ID", method="POST" | Yes | The fallback: if JavaScript fails, the browser still posts the message there. |
accept-charset="UTF-8" | Recommended | Keeps every language intact in the fallback post. |
name on every field | Yes | Fields without a name are not sent. Repeated names (checkboxes) arrive joined with commas. |
Hidden _fh_hp field | Yes | A 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 handler | The 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 use | What you get |
|---|---|
ellieforms:sent event | Fired on the form after a successful send; it bubbles. event.detail is { ok: true, status, id }. |
ellieforms:error event | Fired 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.
Show a sending state
In automatic mode the script takes over the submit. To disable the button while sending, switch to call mode and send from your own handler:
<form id="contact" data-ellieforms="frm_YOUR_FORM_ID" data-ellieforms-mode="call"
action="https://in.ellieforms.com/f/frm_YOUR_FORM_ID" method="POST" accept-charset="UTF-8">
<!-- the same fields, trap and button as above -->
</form>
<script>
const form = document.getElementById("contact");
form.addEventListener("submit", async (event) => {
event.preventDefault();
if (!window.ellieforms) return form.submit(); // script blocked: the plain post still delivers
const button = form.querySelector("button");
button.disabled = true;
document.querySelector(".form-error").hidden = true;
const ok = await window.ellieforms.send(form);
button.disabled = false;
form.hidden = ok;
document.querySelector(ok ? ".form-success" : ".form-error").hidden = false;
});
</script>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.