Guides

Guides16 min read

Outgrow your website builder's forms

When Webflow, Netlify, Carrd or Framer forms hit a cap or a missing feature, keep the form you designed and point it at a form backend instead.

Preet SutharFounder, Ikiform

Keep the form your builder draws and change only where it sends: a custom action on Webflow, Send to URL on Carrd, a webhook destination on Framer, or a plain action on a Netlify-hosted page. The post then goes to a form backend that validates, filters, stores and forwards each submission, so the builder's submission caps and plan gates stop applying to it. Check what you give up first, such as file uploads and the builder's own inbox.

Site builders ship forms because every site needs one. They're built for the first contact form, not the tenth form or the thousandth submission. At some point you hit a wall: a submission cap, a feature that needs a plan you don't otherwise need, a form that only works while the site stays on one host, or an inbox that is your only record of who wrote in.

You don't have to rebuild the form to get past it. Every major builder can send a form somewhere else. This guide explains what changes when it does, how to do it in each builder without losing a submission, and when staying on the builder's forms is the better call.

What changes when the form leaves the builder

A builder form has two halves: the part you see, which the builder draws, and the part that receives the post. Moving to a form backend replaces only the second half. Your layout, fonts and styles stay where they are.

A builder form before and after it posts to a form backendBefore: the builder handles the postAfter: the builder only draws the formyour formdesigned in thebuilderbuilder's formhandlercounts toward theplan's capbuilder inboxor emailexport by handthe same formsame layout andstylesIkiformvalidates, filtersspam, storesemail, webhooks,CSVyour team and yourtoolspostaction URLA builder form before and after it posts to a form backendBefore: the builder handles the postAfter: the builder only draws the formyour formdesigned in the builderbuilder's form handlercounts toward the plan's capbuilder inbox or emailexport by handthe same formsame layout and stylesIkiformvalidates, filters spam, storesemail, webhooks, CSVyour team and your toolspostaction URL
  1. Before: a visitor submits the form, and the builder's own form handler receives the post.
  2. The builder counts it toward the plan's submission cap and keeps it in its inbox or sends it by email.
  3. After: the same form, with the same design, posts to the Ikiform endpoint instead.
  4. Ikiform validates the fields, scores the post for spam and stores it.
  5. Ikiform emails your team, sends signed webhooks, and keeps every submission searchable and exportable as CSV.
Only the destination changes. The builder never sees the post, so its submission count and its form features stop applying to that form.

The limits people hit

Each builder draws its line in a different place. The table summarises what each one says on its own pricing and help pages as of October 2026. Plans change, so check the linked variant page for detail and the builder's site before you decide.

BuilderWhat its forms doWhere people hit the wallThe way out
WebflowStores submissions, emails notifications and exports CSVThe free Starter plan allows 50 form submissions per site in total, and the count doesn't reset. Exported sites get no form handling at allA custom action in the Form Block settings. It works on Starter too
NetlifyDetects data-netlify forms at deploy time and stores postsLegacy plans meter submissions per site per month and upgrade the site to a paid Forms level when it passes the limit. Forms only work on sites Netlify buildsRemove the Netlify attributes and set the form's action
CarrdContact forms email you; signup forms add people to an email toolAny form needs Pro Standard. Custom forms, including Send to URL, need Pro PlusSend to URL on Pro Plus, or an Embed on Pro Standard
FramerSends each submission to email, Google Sheets or a webhookNo cap to speak of. Teams want a stored record with spam status, validation, notifications and more than one destinationAdd the endpoint as a webhook destination, or use a code component

Notice the Framer row. Framer already has webhooks, so moving off its forms is a choice about what happens after the post, not a workaround for a cap. The Framer page is honest about when you don't need Ikiform at all.

Four ways past the limit

A form backend isn't the only answer, and sometimes it isn't the best one.

ApproachGood atTrade-offs
Upgrade the builder planZero migration. Webflow's paid site plans list unlimited submissions; Netlify's credit-based plans make forms freeYou pay for the whole plan to lift one limit. The form stays tied to that builder and host
Embed a form builder, such as Tally or TypeformRich question types, logic and file uploads with no codeAn iframe with its own look and scripts. The design you built in the builder is gone, and limits move to that product's plans
Write your own handler, such as a serverless functionFull control, any logic you likeYou now own spam filtering, rate limits, storage, notifications and retries, on a site you chose a builder for so you wouldn't run code
Point the form at a form backend, such as IkiformKeeps your design. Spam filtering, storage, team email, signed webhooks and CSV export, the same on every builderNo file uploads yet, no builder inbox, and no integrations clicked together inside the builder. Some builders need a paid plan to send anywhere

Upgrade when the builder's forms already do everything you need and the plan is worth it for other reasons too. Move to a form backend when the limit is about the form itself: you want one place for submissions from several sites, you might change builders, or the submissions need to reach other tools reliably. The Netlify Forms comparison goes through that trade in detail for one host.

What you give up

When a form posts somewhere else, the builder treats it as a plain HTML form. Its form features stop applying to that form. Know the list before you switch:

  • The builder's inbox. New submissions appear in Ikiform's dashboard, not the builder's. Old ones stay where they were.
  • The builder's success message, sometimes. Webflow's success and error blocks only run when Webflow handles the post. Carrd's AJAX mode and Framer's webhook destination keep theirs.
  • File uploads. File uploads aren't supported yet. A post with a file gets 422 files_not_supported. Webflow, Netlify and Carrd custom forms all accept files, so check this first.
  • Click-together integrations. There are no one-click integrations. Every tool is reached through a signed webhook, directly or through an automation tool such as Zapier or n8n.
  • The builder's spam filter. Ikiform's honeypot, spam scoring, rate limits and optional human check take over. A reCAPTCHA element added in the builder does nothing with a custom destination; remove it.
If a form needs file uploads, keep that one form on the builder and move the rest. Nothing forces every form on a site to use the same backend.

Point each builder at Ikiform

Create a form in the Ikiform dashboard and copy its endpoint. Then use the builder's own setting for an outside destination. The docs guides for Webflow, Carrd and Framer have the full click path; here is what to change and the one thing most people miss.

Webflow

  1. Select the form inside the Form Block and open Settings.
  2. Under Send to, choose a custom action, paste the endpoint into Action and set Method to POST.
  3. Rename each input's Name to a lowercase id such as email. Webflow fills names from labels, so you'd otherwise get Email and Field 2.
  4. Publish and submit from the webflow.io domain. Custom actions don't run in the Designer.

Easy to miss: Webflow's success block stops showing, because Webflow no longer sees the result. Set Redirect after submit in Ikiform, or add the script from the Webflow docs. Detail and the Starter cap are on the Webflow limit page.

Netlify

  1. Remove data-netlify or netlify, netlify-honeypot and any hidden form-name input.
  2. Set the form's action to the endpoint and method to post.
  3. Move the old thank-you path into Redirect after submit, as a full https: URL.
  4. For JavaScript forms, delete the hidden static copy you kept for Netlify's build, and post to the endpoint instead of to your own site.

Easy to miss: deploy previews live on their own netlify.app subdomains, so your production domain in Allowed domains doesn't cover them. The Netlify page has the code for every framework.

Carrd

  1. On Pro Plus, add a Form, set Type to Custom, then Send to URL, and paste the endpoint.
  2. Set Method to AJAX and Format to Default, so Carrd keeps its On Success and On Failure behaviour.
  3. Give every field an ID or Submitted ID: name, email, message.
  4. On Pro Standard, paste an HTML form into an Embed element instead.

Easy to miss: XML format fails with 415, and a File field fails with 422 files_not_supported. See the Carrd page.

Framer

  1. Give each input a lowercase name. Framer sends the names as JSON keys.
  2. Select the form, and next to Send To choose Add… > Webhook, then paste the endpoint.
  3. In Ikiform, leave Allowed domains empty and the Spam check off, and choose the Relaxed rate limit.

Easy to miss: Framer posts from its servers, not from the visitor's browser, so origin checks and per-visitor rate limits don't work the usual way. The Framer page explains the trade and a signed relay that fixes it.

Squarespace, Wix, WordPress and the rest

Builders without an outside destination setting usually accept an HTML embed. Paste a form like the one below into a code or embed block. It posts with fetch so visitors stay on the page, shows the first field error from Ikiform, and falls back to a normal post if the script doesn't run.

Embed or code block
<form id="enquiry" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post" target="_top">
  <label>Name <input name="name" autocomplete="name" required maxlength="120"></label>
  <label>Email <input name="email" type="email" autocomplete="email" required></label>
  <label>Budget
    <select name="budget">
      <option value="">Not sure yet</option>
      <option value="under_5k">Under $5k</option>
      <option value="5k_20k">$5k to $20k</option>
      <option value="over_20k">Over $20k</option>
    </select>
  </label>
  <label>What are you planning? <textarea name="message" rows="5" required minlength="20"></textarea></label>
  <input type="hidden" name="source" value="builder-embed">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <p id="enquiry-status" role="status" hidden></p>
  <button type="submit">Send enquiry</button>
</form>
<script>
  document.getElementById("enquiry").addEventListener("submit", async (event) => {
    event.preventDefault();
    const form = event.currentTarget;
    const status = document.getElementById("enquiry-status");
    const button = form.querySelector("button");
    button.disabled = true;
    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.replaceChildren(Object.assign(document.createElement("p"), {
          textContent: "Thanks. We reply within two working days.",
        }));
        return;
      }
      const fields = result.error.fields ?? {};
      const first = Object.keys(fields)[0];
      status.textContent = first ? `${first}: ${fields[first][0]}` : result.error.message;
    } catch {
      status.textContent = "Couldn't send. Check your connection and try again.";
    }
    status.hidden = false;
    button.disabled = false;
  });
</script>
  • target="_top" matters when the builder wraps embeds in an iframe. Without it, a plain post would load the thank-you page inside the frame.
  • The hidden _gotcha input is the honeypot. People don't see it; bots that fill every input mark themselves as spam.
  • The hidden source input records which builder or page the enquiry came from, which helps when several sites post to one form.
  • The script posts with fetch, so leave the Spam check off for this form, or remove the script and let the browser post normally, which runs the check without extra code.

The Squarespace, Wix and WordPress guides cover where each builder lets you paste code, and the site builder embed has a styled version.

Who sends the post for each builder, and what that means for allowed domainsWebflowcustomactionvisitor'sbrowserlist yourdomainsCarrdSend to URLor Embedvisitor'sbrowserlist yourdomainsNetlifyplain actionvisitor'sbrowserdomains pluspreviewsFramerwebhookdestinationFramer'sserversleave emptybuildersettingwho postsallowed domainsWho sends the post for each builder, and what that means for allowed domainsWebflowcustomactionvisitor'sbrowserlistyourdomainsCarrdSendtoURLorEmbedvisitor'sbrowserlistyourdomainsNetlifyplainactionvisitor'sbrowserdomainspluspreviewsFramerwebhookdestinationFramer'sserversleaveemptybuildersettingwhopostsalloweddomains
  1. Webflow's custom action makes the visitor's browser post to Ikiform, so list your domains under Allowed domains.
  2. Carrd's Send to URL and Embed also post from the browser, so allowed domains work as usual.
  3. A Netlify-hosted form with a plain action posts from the browser. List the production domain and any preview domains you test on.
  4. Framer's webhook destination posts from Framer's servers with no Origin header, so leave Allowed domains empty, or every post is treated as coming from the wrong site.
Three builders send the post from the visitor's browser. Framer's webhook sends it from Framer, which changes how spam checks and rate limits see it.

Field names are the real migration

Most of the work in moving a builder form is naming. Ikiform stores whatever names the form sends, and every builder generates names its own way:

BuilderWhere the name comes fromWhat you get if you don't set it
WebflowEach input's Name settingThe label, such as Name, Email or Field 2
CarrdSubmitted ID, then IDAn ID generated from the label
FramerEach input's nameWhatever the input was called when you added it
NetlifyThe name attribute in your HTMLYour own names, usually fine already

Rename to short lowercase ids before you go live: name, email, budget, message. Notification emails and CSV columns read better, and an email field becomes the reply-to address of every notification. Once a real submission has arrived, add fields to the Ikiform form so the server enforces types and lengths. Try the enquiry form above with its definition:

Preview

Runs Ikiform's validator in your browser. Nothing is sent.

The same fields as the embed above. Paste the definition on the form's Fields tab and Ikiform checks every post against it, however the builder sent it.
Define fields after you've seen one real submission, not before. Builders add fields you didn't ask for, such as Carrd's UTM fields, and a definition that doesn't list them turns every post into a 422 with an Unknown field error.

Staging domains and allowed domains

Builders publish to a staging address before your own domain. Posts from a domain that isn't on the form's Allowed domains are stored as spam, or refused with Reject. List every address you'll test from:

BuilderStaging addressAdd
Webflowyour-site.webflow.ioThat host, plus your domain
Carrdyour-site.carrd.co, or crd.co on ProThat host, plus your domain
Netlifyyour-site.netlify.app, and previews such as deploy-preview-42--your-site.netlify.appEach host you test on. A preview isn't a subdomain of your-site.netlify.app
Framer, webhookNot applicableNothing. Leave the list empty

Don't add a whole shared host such as webflow.io or netlify.app. That would let every site on that host post to your form. Subdomains of a domain you list are already allowed, so example.com covers www.example.com.

Bring your old submissions along

Ikiform has no import, so past submissions stay where they were. Export them before you switch, and before any plan change could remove them:

  • Webflow: download each form's submissions as CSV from the site's Forms settings.
  • Netlify: download each form's submissions as CSV from the Forms section of the site.
  • Carrd: contact and custom email forms deliver each message by email, so your inbox is the record.
  • Framer: the email inbox or Google Sheet you sent submissions to is the record.

To keep one history, put the old export and an Ikiform CSV export on two tabs of one Google Sheet and stack them. This formula takes the date, name, email and message columns from each, newest first. Adjust the column letters to match your files:

Google Sheets
=SORT({
  Webflow!A2:A, Webflow!C2:C, Webflow!D2:D, Webflow!E2:E;
  Ikiform!B2:B, Ikiform!F2:F, Ikiform!G2:G, Ikiform!H2:H
}, 1, FALSE)

An Ikiform export starts with id, created_at, form and status, then one column per field, and holds up to 100,000 rows per file.

Switch without losing a submission

  1. Create the Ikiform form, add your notification recipients, and add your staging and live domains under Allowed domains.
  2. Change the destination on the staging site and submit a real test from a phone and a laptop.
  3. Check the submission's field names in the dashboard. Rename anything generated, publish staging again, retest.
  4. Publish to your live domain at a quiet hour and send one more test.
  5. Keep the builder's notification on for a week if it still receives anything, such as a second form you didn't move, then turn it off.
  6. Export the builder's old submissions and keep the file with the new history.

During the first week, check the Spam filter in the Ikiform dashboard every day or two. A real enquiry stored as spam gets the same success answer as a real one, so the visitor never knows. Mark it as not spam and its email and webhooks go out then. Notification emails go to up to 10 confirmed recipients.

Pick your situation

Each builder has its own limit, its own setting for an outside destination, and its own gotchas. These pages go through one builder at a time.

Check it works

Run this on staging first, then once on the live site. Ikiform has no free plan. Testing is free: a workspace without a plan accepts 50 test submissions a month from localhost. To go live, pick Pro from $6/mo for 500 submissions, or pay once: 10,000 submissions for $49 or 50,000 submissions for $149, with credits that never expire. See pricing.

  1. Under the form's Allowed domains, add your site's domain, plus localhost while you develop. Leave it empty to accept posts from anywhere.
  2. Publish to the builder's staging domain. Custom destinations don't run in the editor or designer.
  3. Fill in the form on your page and submit it. You land on your thank-you page, or Ikiform's hosted one.
  4. Open Submissions in the dashboard. The new submission is there with every field you sent.
  5. Read the field names on that submission. They should be your lowercase ids, not labels or generated names.
  6. Check the inbox of each notification recipient. Each gets an email with the fields, and Reply goes to the submitter when the form has an email field.
  7. Post with the honeypot filled in, _gotcha=bot. It still gets a success answer, but the submission is stored as spam and sends no email or webhook.
  8. Nothing arrived? Switch the dashboard's status filter to Spam. Spam gets the same success answer as a real submission.
  9. Submit once more from your live domain after you publish there.

Troubleshooting

ProblemWhat to do
A 404 not_found response after submitting a Webflow formMethod is GET, so the browser opened the endpoint like a link. Set it to POST and publish again.
Carrd shows On Failure on every submitFormat is XML (415), a File field is present (422), or the field IDs don't match a field definition. Use Default, remove the file field, and match the IDs.
Framer reports failed webhook deliveriesIkiform refused the post. Clear Allowed domains, turn the Spam check off for that form, and match input names to your fields.
Netlify still shows the form in its Forms tabAn old deploy or a static copy of the form still has data-netlify. Remove it everywhere and deploy again.
403 origin_not_allowed, or every post lands in spamThe page's domain isn't in the form's Allowed domains. Add it, plus localhost for local tests. Subdomains of a listed domain are allowed.
422 validation_failedThe post doesn't match the form's field definition. error.fields names each field and the reason. Match the input name to the field id.
422 files_not_supportedThe form has an <input type="file"> with a file chosen. File uploads aren't supported yet; remove the input or ask for a link instead.
The submission is in the dashboard but no email or webhook arrivedIt was stored as spam. Spam sends nothing. Open it under the Spam filter to see the reasons, and mark it as not spam to send its email and webhooks.

Questions

Stuck on a step, or want a guide for your situation? Email hello@ikiform.com.