splitforms.com
All articles/ TUTORIALS9 MIN READPublished June 21, 2026

How to Add a Working Contact Form to a Bolt.new App (2026)

Bolt.new builds a full-stack app from a prompt, but the contact form still needs somewhere to send submissions. Wire a real backend in 2 minutes — email, dashboard, webhooks, no SMTP.

✶ Written by
splitforms.com / blog

Founder of splitforms — the form backend API for developers. Writes about form UX, anti-spam, and shipping web apps without backend code.

Why a Bolt.new form submits to nowhere

Bolt.new turns a prompt into a working app inside StackBlitz's in-browser WebContainer. It can scaffold routes, components, even a backend — which is exactly why the broken contact form is so easy to miss. The form looks wired: it validates, it shows a success toast. But the generated onSubmit is usually a placeholder that never delivers the message. Nobody gets an email; nothing is stored.

Making it real the "native" way means building an API route inside the project, signing up for an email provider, adding its API key, verifying a sending domain, and handling spam — then making sure all of that survives when you export or deploy the app. For a contact, waitlist, or lead form, that's a lot of surface area for "email me the submission."

The shortcut: point the form at a hosted backend. The submission leaves the browser, hits one endpoint, and you get email, a dashboard, and spam filtering with nothing added to your Bolt project except a URL.

Step 1: Get a free splitforms access key (1 minute)

Free tier is 500 submissions/month with dashboard storage and AI spam filtering; Starter adds email forwarding and webhooks — no credit card.

  1. Go to splitforms.com/login, enter your email, paste the 6-digit code
  2. Copy the access key (sf_live_...)
  3. Set the notification email under Settings → Notifications

The key is public and safe in client code. Comparing options first? See the free form backend comparison.

Step 2: Repoint the submit handler

Keep Bolt's generated form. Replace the submit handler with this. The easiest path is to paste a prompt into Bolt's chat:

Change the contact form so that on submit it POSTs the form data
to https://splitforms.com/api/submit via fetch, including a field
"access_key" set to "YOUR_ACCESS_KEY". Keep all existing styling and
validation. Show the current success state on a 200 response and an
inline error message otherwise.

Or wire it by hand — a clean React handler that works in any Bolt-generated app:

const ACCESS_KEY = "YOUR_ACCESS_KEY"; // public identifier, safe in client code

async function onSubmit(e) {
  e.preventDefault();
  const data = new FormData(e.currentTarget);
  data.append("access_key", ACCESS_KEY);

  const res = await fetch("https://splitforms.com/api/submit", {
    method: "POST",
    body: data,
  });

  if (res.ok) {
    e.currentTarget.reset();
    // show success / navigate to /thanks
  } else {
    // show an inline error
  }
}

Three essentials: append access_key to the FormData, keep a name on every input (those become your inbox fields), and add a hidden honeypot input — <input name="botcheck" type="checkbox" tabIndex={-1} style={{ display: "none" }} /> — to stop bots without a CAPTCHA. The fetch-and-FormData details are in send form data to email with fetch.

Step 3: Test and publish

Submit a test entry from Bolt's preview. Within ~5 seconds you should get a notification email and see the submission in your splitforms dashboard. Because the POST goes straight to splitforms, it behaves the same in the WebContainer preview and after you publish or export the app.

Before launch, add your published domain to Allowed Domains in the splitforms security tab. If a submission doesn't arrive, check the dashboard first (present-but-no-email is a forwarding issue; absent means the POST didn't reach splitforms). Checklist: contact form not working.

What to do next

FAQ

Doesn't Bolt.new already build a backend? Why doesn't the form work?

Bolt.new can scaffold full-stack apps, but a generated contact form usually ships with a placeholder submit handler — it validates and shows a success state without actually delivering the message anywhere. To make it real you either build out an API route plus an email provider inside the StackBlitz project, or point the form at a hosted backend. The hosted route is a one-line change and avoids adding an email service and SMTP credentials to your Bolt project.

Will adding a custom endpoint conflict with Bolt's WebContainer environment?

No. Bolt.new runs in StackBlitz's in-browser WebContainer, and a fetch POST to an external HTTPS endpoint works there exactly like it does in production. Because the form posts directly to splitforms from the browser, there's no server process to keep alive inside the WebContainer and nothing extra to deploy when you export or publish the app.

Is the access key safe to leave in a Bolt.new project?

Yes. The splitforms access key is a public identifier designed to live in client-side code. It is not a secret. Abuse is handled server-side with rate limiting, the Allowed Domains setting, and AI spam classification. If a key is ever misused, rotate it from the dashboard and re-run your Bolt app. You don't need to hide it in an environment variable, though you can.

Can I keep Bolt's generated design and just change where it submits?

Yes. Keep all of Bolt's generated markup, styling, and validation. You only replace the submit handler so it POSTs to the splitforms endpoint. The look and feel stay identical — you're changing the destination of the data, not the form itself.

What if my Bolt app has a real backend and I want submissions in its database?

Then use both. Let the form post to splitforms for email, dashboard, and spam filtering, and add a splitforms webhook that POSTs each submission to your Bolt app's API route to store a copy. You get notifications and a managed inbox without giving up a record in your own database.

About the author
✻ ✻ ✻

Get your free contact form API key in 60 seconds.

500 free form submissions per month. No credit card. No SDK, no PHP, no plugin. Drop one POST endpoint in your form and submissions land in your dashboard. Starter adds inbox delivery.

Generate access key →Read the docs
founders pricing locked in · early access open