Webflow
Send a Webflow Form Block to Ikiform with a custom action, keep Webflow's success and error states with a short script, and allow your webflow.io staging site.
Webflow's Form Block can post to any URL. Point its action at your Ikiform endpoint and the form keeps the layout and styles you built in the Designer, while Ikiform validates, filters spam, stores, emails and sends webhooks.
What a custom action changes
- Webflow only processes a form when it is the destination. With a custom action, the browser posts straight to Ikiform, so the submission doesn't appear in Webflow's form submissions and Webflow sends no notification email.
- Webflow's own destinations can't run next to a custom action. Remove them under Send to before you add Ikiform.
- Webflow's success and error blocks (
.w-form-doneand.w-form-fail) and the form's own redirect setting stop working, because Webflow never sees the result. Visitors land on Ikiform's thank-you page or on your Redirect after submit URL. Step 4 brings Webflow's blocks back.
Set up the form
Point the form at Ikiform
Select the form inside the Form Block and open the Settings panel. Under Send to, choose a custom action, paste your endpoint into Action and set Method to POST.
Action https://ikiform.com/f/frm_xxxxxxxxxxxxxxxxLeaving the method as GET makes the browser open the endpoint as a page, which answers
404 not_found. Ikiform only takes posts.Name the fields
Each input's Name setting becomes the field name in Ikiform. Webflow fills it from the label, so you get names like
Name,EmailandField 2. Rename them to the ids you want to see, such asname,emailandmessage.- If you define fields on the Ikiform form, the names must match their ids exactly. Ids are lowercase snake_case, so
Emailandemailare different fields. - Remove any reCAPTCHA element from the form. Ikiform doesn't verify it, and its
g-recaptcha-responsevalue would arrive as an extra field. Use Ikiform's spam check instead.
- If you define fields on the Ikiform form, the names must match their ids exactly. Ids are lowercase snake_case, so
Add a honeypot
Add an Input to the form, set its Name to
_gotcha, and hide it with Display: none in the Style panel. In Custom attributes, addtabindexset to-1andautocompleteset tooffso keyboards and password managers skip it. On a paid site plan you can paste this into a Code Embed inside the form instead:Code Embed <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />Choose what happens after submit
The simplest option is a thank-you page. Create one in Webflow, publish it, and paste its full URL into Redirect after submit in the Ikiform form's settings.
Keep Webflow's success and error blocks
To stay on the page, post with
fetchand toggle Webflow's blocks yourself. Paste this under Page settings > Custom code > Before </body> tag, or in the site's footer code to cover every form. It shows Ikiform's error message inside the error block and uses the button's Waiting text while sending.Before </body> tag <script> document.querySelectorAll('form[action^="https://ikiform.com/f/"]').forEach((form) => { const wrapper = form.closest(".w-form"); const done = wrapper?.querySelector(".w-form-done"); const fail = wrapper?.querySelector(".w-form-fail"); const button = form.querySelector('[type="submit"]'); form.addEventListener("submit", async (event) => { event.preventDefault(); const label = button?.value; if (button) { button.disabled = true; button.value = button.dataset.wait || label; } try { const response = await fetch(form.action, { method: "POST", headers: { Accept: "application/json" }, body: new FormData(form), }); const result = await response.json(); if (result.ok) { form.style.display = "none"; if (fail) fail.style.display = "none"; if (done) done.style.display = "block"; return; } const text = fail?.querySelector("div") ?? fail; if (text) text.textContent = result.error.message; if (fail) fail.style.display = "block"; } catch { if (fail) fail.style.display = "block"; } finally { if (button) { button.disabled = false; button.value = label; } } }); }); </script>Custom code and the Code Embed element need a paid site plan or a Workspace plan, and neither runs in the Designer. Publish to see them work.
The script posts with fetch, so a form whose spam check is set to Ikiform answers 403 challenge_required instead of showing the check page. Use the script with the check off, or skip the script and let the browser post normally, which runs the check with no extra code.
Allowed domains
If you set allowed domains, list every address the form is published to. Subdomains of a listed domain already match.
| Where the form runs | Add to Allowed domains |
|---|---|
| Your custom domain | example.com, which also covers www.example.com |
| Webflow staging | your-site.webflow.io |
| The Designer canvas | Nothing. Custom actions and custom code don't run there. |
- Never add
webflow.ioon its own. Every site on that host would match, including other people's.
Test checklist
- Publish to your
webflow.iostaging domain. Forms with a custom action only post from the published site. - Submit the form and open the form's submissions in Ikiform. The new submission should be listed under received, not spam.
- Check the field names match what you set in step 2, and that the honeypot isn't listed: names starting with
_are never stored. - Confirm you land on your thank-you page, or see Webflow's success block if you added the script.
- Publish to your custom domain and submit once more from there.
Troubleshooting
| What you see | Why | Fix |
|---|---|---|
404 not_found page after submit | Method is GET, so the browser opened the endpoint like a link | Set Method to POST and publish again. |
| Ikiform's thank-you page instead of Webflow's success message | Webflow's success block only runs when Webflow handles the form | Set Redirect after submit, or add the script from step 4. |
Submissions arrive under the spam filter with origin_mismatch | The page that posted isn't on the form's allowed domains | Add the host from the table above. With Reject chosen, the same posts get 403 origin_not_allowed instead. |
422 validation_failed listing an Unknown field | A field name such as Email or g-recaptcha-response isn't in the form's field definition | Rename the input to the field id, or remove the reCAPTCHA element. |
| The script does nothing | You're testing in the Designer, the site has no paid plan, or the action doesn't start with https://ikiform.com/f/ | Test on the published site and check the Action has no spaces. |
The error block says Complete the human check, then send the form again. | The spam check is set to Ikiform and the script posts with fetch | Turn the check off for this form, or remove the script. |