August 31, 2026 · NBForms Team
Framer Contact Form With No Backend — and a Redirect Setting to Leave Alone
Framer's Form component already speaks webhook and JSON. Here's exactly how to point one at NBForms, and one settings-page checkbox that will quietly break every submission if it's checked.
Framer's Form component doesn't need an embed or a line of code to reach an external service — it already has a webhook destination built in, sending a JSON body to whatever URL it's pointed at. The setup is close to trivial, closer than the equivalent on most page builders. The one thing worth getting right before flipping it on is a setting that looks entirely unrelated and will make Framer treat a working, successfully-stored submission as broken if left checked.
Photo by Christin Hume on Unsplash
Setting up the webhook, exactly
Select the Form component on the canvas, find Send To in the right-hand panel, click Add,
and choose Webhook. Paste in the endpoint — https://api.nbforms.com — and that's the whole
native setup; Framer's own docs are explicit that the URL just needs to start with https://.
Nothing else in the Designer changes: the form still looks and behaves exactly as designed, and
Framer's own Email Inbox destination can stay active alongside the webhook if both are
wanted.
JSON, not FormData
Every code-based framework example sends FormData — Framer's webhook doesn't. It posts a JSON
body instead, using each input's name as a key and its value as the value, entirely by Framer's
own design rather than anything configured per-site. NBForms doesn't need FormData specifically;
Fastify's own JSON parser handles a webhook's application/json body exactly like it handles a
plain HTML form's URL-encoded one, landing in the same field list either way. Nothing about
adding a field later changes: name an input in the Designer, and it starts appearing as a new
dashboard column the next time the webhook fires.
The hidden field, done natively
Unlike some page builders, Framer's own field picker supports a hidden input directly — no embed,
no workaround. Add an Input field, open its settings, and there's a dedicated Hidden property
alongside a settable Name and Value. That's where _token goes, with the form's own
token pasted in as the fixed value. One specific mistake is worth naming because it's easy to
make by instinct: toggling the field's Visible property off instead of using Hidden looks
like it should do the same thing, and doesn't — an invisible-via-Visible field is excluded from
the submission entirely, which means a token set that way never reaches the webhook at all. The
Hidden property is the one that keeps a field in the submitted data while keeping it off the
rendered page.
The redirect setting that will break every submission
This is the one to get right before publishing anything. Framer's webhook requires a direct 2xx response — its own documentation states plainly that a 3xx redirect isn't followed, and a response that isn't 2xx gets retried automatically, up to 5 times. NBForms' redirect setting, when a form has one configured, responds to every request with a 302 to that URL — a behavior built for a plain HTML form's browser navigation, not a server-to-server webhook call. Set a redirect URL on a form that's also wired to a Framer webhook, and Framer will read every single successful submission as a failure, retry it repeatedly, and eventually mark it failed outright, while the submission itself was actually stored just fine on NBForms' side the whole time. The fix is simple once it's known: leave the redirect URL blank on any form connected to Framer this way. Framer's own on-page confirmation state (configured separately in the Form component itself) is what a visitor sees after submitting — NBForms' redirect setting has no role to play here and should stay off.
File uploads: the one thing this doesn't cover
Worth being direct about rather than letting it surface as a surprise later: Framer's native
Form component has no file-upload field at all, in a way that's genuinely different from every
code-based framework covered elsewhere on this blog, where a plain <input type="file"> just
works. Third-party Framer components fill the gap by uploading a file straight to a cloud storage
provider — Google Drive, Cloudinary, Supabase, Cloudflare R2, depending on the component — and
then passing only the resulting URL into the form's own submission as a normal text value. That
URL reaches NBForms as a regular field, readable in the dashboard like any other, but the file
itself was never in NBForms' hands; it lives wherever that third-party component uploaded it. A
Framer contact form asking for a name, an email, and a message doesn't run into this at all — it
only matters the moment "attach a file" becomes one of the fields.
Framer's own confirmation state is separate from all of this
None of the webhook mechanics above touch what a visitor actually sees after clicking submit — that's configured directly on the Form component itself, as its own success and error states, independent of what any webhook destination returns. A visitor sees Framer's own confirmation regardless of whether NBForms' response was a 202 or something else; the redirect-setting warning above is about Framer's retry logic treating the submission as failed behind the scenes, not about what shows on the page. The two are easy to conflate because they both relate to "what happens after submit," but one is entirely a Framer Designer setting and the other is entirely about how NBForms' response gets interpreted by Framer's webhook delivery system.
What the webhook secret protects, and why NBForms doesn't need it
Framer supports a signing secret for its webhooks — a value a receiving server can use to verify,
via the Framer-Signature header, that a request genuinely came from Framer and not somewhere
else pretending to be it. NBForms doesn't inspect that header, and that's a fair thing to be
upfront about rather than imply otherwise: authenticity here comes from the form's own token
instead, plus the spam filtering that already runs on every submission regardless of what sent
it. The signature exists for someone writing their own custom backend to trust a webhook payload
blindly; NBForms was never trusting the payload blindly to begin with; the two safeguards solve
overlapping but not identical problems, and Framer's secret is genuinely unnecessary to configure
in this pairing.
What it doesn't do
Same scope as any lightweight form backend: this receives a submission, filters it for spam, and emails an alert — it isn't a place to run business logic. No payment processing, no multi-step form logic branching on an earlier answer, and no automatic reply sent back to whoever submitted, beyond the alert and Framer's own on-page confirmation state. A Framer site that needs a form to trigger something specific — a CRM write, an internal workflow — still routes that through its own destination or Zapier/Make step; a contact or inquiry form usually doesn't need that.
For a Framer page with no site around the form at all, hosted form pages with no website
covers the same subdomain approach independent of Framer. And for what happens to a submission
once it lands, regardless of which page builder sent it, see
how server-side spam filtering works — the filtering runs the
same way whether the request arrived as JSON from a Framer webhook or FormData from a hand-written
<form> tag.
Frequently asked questions
Does this need a code component or a custom embed?
No — Send To > Webhook is a native destination on Framer's own Form component, configured entirely in the right-hand panel. A code component is only relevant if the form needs behavior Framer's own component doesn't offer at all.
Why does Framer send JSON instead of the usual FormData?
Because that's how Framer's webhook destination is built — it posts a JSON body with each input's name as a key, by design, not as something a site owner configures. NBForms accepts JSON the same way it accepts FormData, so nothing needs to change on the receiving end.
Will Framer retry a submission that fails?
Yes — up to 5 times, if the webhook doesn't return a direct 2xx response. That retry logic is also why the redirect setting above matters: a 302 counts as a non-2xx response to Framer, not a success.
Does the Framer-Signature header do anything on NBForms' side?
No — that header is Framer's way of letting a custom backend verify a request really came from Framer, and NBForms doesn't inspect it. Submissions are still identified by the form's own token and filtered for spam independently of that signature.
Can I still use Framer's own Email Inbox destination alongside a webhook?
Yes — Send To supports more than one destination at once, so Framer's native inbox and a webhook to NBForms can both be active on the same form without conflicting.