splitforms.com

Contact form · Framer

Contact form for Framer websites

Framer's built-in forms send to a single email, gate webhooks behind paid plans, and limit free submissions. Paste a Code Component instead — same canvas drag-and-drop, real backend, 200 free submissions total, dashboard search, and signed webhooks from Pro.

  • 500 free / mo
  • 14ms latency
  • No backend code
Framer contact form — copy-paste code for splitforms

No backend code

No server, API route, or SDK. Your Framer form posts straight to one endpoint.

Straight to your inbox

Every submission is emailed to you and saved to a searchable dashboard — spam filtered before it reaches you.

Design without limits

It's your own Framer markup and styles. Splitforms is only the backend, so nothing constrains how the form looks.

Copy-paste ready

Your Framer contact form, ready to paste.

Replace YOUR_ACCESS_KEY with the key from your dashboard — that's the whole integration. No SDK to install, no build step, just the tsx you already write.

Generate access key
contact.tsx
// ContactForm.tsx — paste into Framer's Code Components panel
// Insert the resulting component into any frame on the canvas.
import { useState } from "react";
import { addPropertyControls, ControlType } from "framer";

export default function ContactForm({ accessKey = "YOUR_ACCESS_KEY" }) {
  const [status, setStatus] = useState<"idle" | "loading" | "ok" | "err">("idle");

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setStatus("loading");
    const formData = new FormData(e.currentTarget);
    formData.append("access_key", accessKey);

    const res = await fetch("https://splitforms.com/api/submit", {
      method: "POST",
      body: formData,
    });
    const data = await res.json();
    setStatus(data.success ? "ok" : "err");
    if (data.success) e.currentTarget.reset();
  }

  return (
    <form onSubmit={handleSubmit} style={{ display: "grid", gap: 12 }}>
      <input name="name"    placeholder="Name"    required />
      <input name="email"   type="email" placeholder="Email" required />
      <textarea name="message" placeholder="Message" required />
      <input type="checkbox" name="botcheck" style={{ display: "none" }} tabIndex={-1} />
      <button type="submit" disabled={status === "loading"}>
        {status === "loading" ? "Sending…" : "Send"}
      </button>
      {status === "ok"  && <p>Thanks!</p>}
      {status === "err" && <p>Something went wrong.</p>}
    </form>
  );
}

addPropertyControls(ContactForm, {
  accessKey: { type: ControlType.String, title: "Access Key" },
});

How to add it

How to add a contact form to a Framer website.

To add a contact form to a Framer website you need three things: a free splitforms access key, the tsx snippet above, and your key pasted into it. No backend, server, or SDK — the form posts to one URL and every submission lands in your inbox and dashboard.

Get your free splitforms access key

Sign up at splitforms.com, verify your email, and copy your access key from the dashboard. No credit card required.

Drop the Framer snippet into your project

Copy the Framer code example into your project and replace YOUR_ACCESS_KEY with the key from step 1.

Receive submissions in your dashboard

Submissions arrive in the splitforms dashboard within seconds. Free includes inbox delivery; Pro adds Slack, Discord, Sheets, or any signed webhook URL.

Where submissions go

Where do your Framer form submissions go?

Every submission is emailed to you and saved to a searchable dashboard — spam filtered before it ever reaches you. Search, export to CSV, or forward it to a webhook or Slack on Pro.

  • 200 submissions total, free to start
  • Honeypot + AI spam classifier on every plan
  • Signed webhooks to Slack, Discord, your server
Framer contact form submissions in the splitforms dashboard

No backend needed

Do you need a backend for a Framer form? No.

Your Framer form posts standard FormData to one URL. Splitforms validates the access key, runs the spam classifier, and forwards it to your email — so there's no server, API route, or database for you to build or maintain.

  • Drop-in Framer Code Component — drag onto any frame
  • Access key exposed as a property control in the canvas
  • No Framer paid-plan upgrade required for the backend
How splitforms processes a Framer form submission

Best practices

What a production-ready Framer form needs.

The difference between a form that works in the demo and one that survives launch traffic — the production-tested defaults, in priority order.

  • Use addPropertyControls to expose the access key as a property — don't hardcode it. Then designers can swap keys per page or per environment without touching code.
  • Style the form with inline style objects, not CSS modules. Framer's bundling doesn't transform CSS imports inside Code Components.
  • Set display: 'grid', gap: 12 on the form for consistent spacing — Framer's flex defaults can fight your form layout.
Production-ready Framer contact form best practices

How SplitForms works

From form to workflow in 3 simple steps.

Connect your form, collect every submission, and send data where it needs to go — without building backend infrastructure.

A SplitForms contact form submission launching straight to your inbox

Add your endpoint

Point your form to your unique SplitForms endpoint. That's it.

HTML form pointing at a SplitForms submit endpoint

Receive submissions

We instantly capture and organize every submission in your inbox.

Submissions inbox with searchable leads and status pills

Route anywhere

Send data to email, spreadsheets, CRMs, webhooks, and 7,000+ apps.

Generic integration tiles for email, sheets, chat, CRM, automate, and webhook

No credit card required. Set up in under 60 seconds.

Connect & automate

Connect your favorite tools and automate everything

SplitForms works with the destinations you route to and the platforms you build on — from Slack and Sheets to WordPress, Shopify, and Next.js. And with Stripe connected, your forms can take payments too.

Connect your SplitForms form to Slack, Google Sheets, Mailchimp, Zapier and more
NewTake payments on your formsDeposits, bookings, order forms — submitters check out through Stripe and the money goes straight to your Stripe account. Included on every paid plan.See plans →

Trusted by indie teams and agencies shipping forms worldwide

PETAL/COKRAFT.DELINEAR-XBUILD.DEVSTUDIO 71MERIDIANFRAME&CO

Testimonials

Loved by developers shipping at every scale.

40 quotes on record — from indie hacks to agency migrations.

Questions

Framer contact form questions.

View all FAQs
How do I add a custom contact form to Framer?

Open the Code Components panel in Framer (sidebar → Components → New Code Component). Paste the snippet above. Save. The component appears in the Insert menu — drag it onto any frame. Set the accessKey property in the right panel.

Does splitforms work with Framer's published sites?

Yes. Framer's published sites are static React + JS, and Code Components run in the browser. The form posts directly to splitforms.com — no Framer-side configuration beyond the Code Component itself.

How do I handle form errors in Framer?

Use a status state with four values (idle/loading/ok/err) inside the Code Component. Render error messages from the splitforms response. Style them with inline styles since Framer's CSS modules don't apply inside Code Components.

Can I use splitforms with Framer's built-in form widget too?

Not directly — Framer's built-in form widget posts to Framer's backend. Replace it with the Code Component to use splitforms. The Code Component renders inside Framer just like a native widget.

How do I customize the success / redirect behavior?

Two options. (1) Render an inline success message or set window.location after a successful fetch. (2) For a native form post, configure the absolute thank-you URL in Dashboard → Form settings → Redirect. Submitted redirect fields are ignored.

Does this work in Framer's preview / does it work with Framer Sites and Framer Web?

Yes — both. Framer's preview executes Code Components (so you can test the form in the editor), and the published site embeds them as React components. Splitforms-side, lock the access key to both your *.framer.app domain and your custom domain.

Can I add the form without writing a Code Component?

Yes. In the Framer editor use Insert → Embed and choose HTML, then paste a plain splitforms <form> (or a self-contained iframe with the form in its srcdoc). This drops an Embed component onto the canvas wherever the form should live — a contact section, a footer, or a dedicated Contact page. The form posts straight to splitforms with no external scripts, and the hidden honeypot field still stops bots. The Code Component route is better when you want property controls and inline success states; the Embed route needs zero React knowledge.

addPropertyControls must be the LAST statement in the file

Framer reads property controls only if addPropertyControls(Component, {...}) is called after the component is exported. If you put it before the export or wrap it in a conditional, the access-key control disappears from the right panel and you can't set the key visually.

Framer's canvas re-renders the component on every prop change

Editing the access key in the right panel re-mounts the form mid-edit. If a user is testing the form when you change the key, their status === 'loading' state resets to 'idle' visually but the in-flight fetch still completes. Not a bug in production — only an editor quirk.

Framer's published page CSP blocks splitforms.com unless you set it

Framer's published sites have a default Content Security Policy that allows known integrations. Splitforms isn't on the default allowlist — you may need to add connect-src https://splitforms.com via Framer's Site Settings → Custom Code → Head HTML, inside a <meta http-equiv="Content-Security-Policy" content="…"> tag.

Code Components don't get Framer's font system by default

If you use style={{ fontFamily: '...' }} in a Code Component, you have to import the font manually — Framer's site fonts only auto-apply to canvas-built elements. Use font-family: inherit to inherit from the parent frame.

Form fields don't focus visibly without explicit styling

Browser-default focus rings are sometimes hidden by Framer's reset CSS. Add :focus { outline: 2px solid currentColor; outline-offset: 2px; } in your component's styles — accessibility requires a visible focus indicator.

Framer's Smart Components break Code Component state on layout swap

If your contact form Code Component lives inside a Smart Component variant (e.g. a 'Mobile' variant of a header), Framer re-instantiates the entire Code Component when switching variants — losing your useState for status. A user mid-submission who rotates their device sees the form reset to 'idle' while the fetch is still in flight, then a stale success/error notification when the request resolves into a now-unmounted component (React logs a 'state update on unmounted component' warning). Either lift the form out of any Smart Component variant, or persist status to sessionStorage and rehydrate on mount.

How does Framer handle forms without splitforms?

Framer's built-in form widget delivers submissions to a single email address (configured per form) with no dashboard for managing submissions, no webhooks below the Pro plan, and no spam filtering beyond Framer's basic bot detection. CMS-driven Framer forms inherit the same constraints. The native flow works for a portfolio's contact form; it falls apart for any setup that needs Slack/Discord notifications, multiple recipients, CSV export, or tagged form-name routing. Replacing it means writing a Code Component — Framer's mechanism for embedding custom React. That's the pattern splitforms uses: a Code Component with the access key as a property control, dropped onto the canvas like a native widget.

Any deployment notes for shipping Framer to production?

Framer publishes sites to its own CDN — there's no Vercel/Netlify config to manage. The form posts cross-origin to splitforms regardless. Framer's published sites have a default Content Security Policy that may block connect-src to splitforms.com on some plans; if submissions silently fail, add <meta http-equiv="Content-Security-Policy" content="connect-src https://splitforms.com"> via Site Settings → Custom Code → Head HTML. Lock the access key to BOTH your *.framer.app preview URL AND your custom domain — Framer serves both with different Origin headers. Framer's preview environment runs Code Components live, so you can test the form before publishing.

Simple pricing

Start free. Scale when you need more.

Choose a plan that fits your workflow — from a free form endpoint to full automations, exports, Stripe payments, and higher submission limits.

Free

$0
 

No card required

Best for testing

For side projects and indie devs.

  • 200 submissions total (one-time)
  • Unlimited forms
  • Email notifications included
  • Honeypot spam filtering
  • Submissions dashboard
  • MCP setup stays free
  • No credit card required

3-Year

$59/ first 3 years
was $99 · save 40% · new-user price

Pay $59. 3 years sorted.

  • 15,000 submissions / mo
  • Unlimited forms
  • Everything in Pro
  • $59 for 3 years, then $59/year
  • Long-term discount
  • Priority support included
  • Vote on the roadmap

No credit card required on Free • Cancel anytime