How to Add a Contact Form to Framer
Framer doesn't have a built-in form backend. Here's how to add a working contact form to any Framer site using a Code Component and Formboost — in under 10 minutes.
How to Add a Contact Form to Framer
Framer is one of the best tools for building beautiful marketing sites, but it doesn't have a native form backend. Submissions from Framer's built-in form component go nowhere unless you connect a third-party service. Here's how to build a fully functional contact form in Framer using a Code Component and Formboost.
Why Use a Code Component?
Framer's built-in form widget is limited — it doesn't give you control over where submissions go, and it doesn't integrate with tools like Slack, Discord, or your CRM. A Code Component lets you write a React component with full control over the form markup, styling, and submission behavior.
Step 1: Create a Formboost Endpoint
Sign up at dashboard.formboost.app and create a new endpoint. You'll get a URL like:
https://formboost.app/f/YOUR_ENDPOINT_ID
Copy that URL — you'll need it in the next step.
Step 2: Create the Code Component
In Framer, go to Assets → Code → New Code File. Name it ContactForm and paste the following:
1export default function ContactForm() {
2 return (
3 <form
4 action="https://formboost.app/f/YOUR_ENDPOINT_ID"
5 method="POST"
6 style={{ display: "flex", flexDirection: "column", gap: 12 }}
7 >
8 <input
9 type="text"
10 name="name"
11 placeholder="Your name"
12 required
13 style={{ padding: "8px 12px", borderRadius: 6, border: "1px solid #ccc" }}
14 />
15 <input
16 type="email"
17 name="email"
18 placeholder="Email address"
19 required
20 style={{ padding: "8px 12px", borderRadius: 6, border: "1px solid #ccc" }}
21 />
22 <textarea
23 name="message"
24 placeholder="Your message"
25 rows={4}
26 style={{ padding: "8px 12px", borderRadius: 6, border: "1px solid #ccc" }}
27 />
28 <button
29 type="submit"
30 style={{
31 padding: "10px 20px",
32 background: "#0070f3",
33 color: "#fff",
34 border: "none",
35 borderRadius: 6,
36 cursor: "pointer",
37 }}
38 >
39 Send
40 </button>
41 </form>
42 )
43}Replace YOUR_ENDPOINT_ID with your actual endpoint ID.
Step 3: Add It to Your Page
Drag the ContactForm component from the Assets panel onto any page or frame. You can resize and reposition it like any other element.
Step 4: Add a Thank-You Redirect (Optional)
By default, Formboost shows its own confirmation page after submission. To redirect to your own page instead, add a hidden field inside the form:
1<input type="hidden" name="_redirect" value="https://yoursite.framer.website/thank-you" />Create a simple thank-you page in Framer and point the redirect at its URL.
Step 5: Publish and Test
Publish your Framer site, then submit the form. The submission appears in your Formboost dashboard within seconds, and you'll get an email notification.
What You Get
- Email notifications on every submission
- AI spam filtering — no bots in your dashboard
- Submission dashboard — search, filter, and export
- Webhooks — forward to Slack, Discord, Zapier, or your own backend
Want More Control?
For AJAX submission (no page redirect at all), you can use fetch inside the component:
1import { useState } from "react"
2
3export default function ContactForm() {
4 const [sent, setSent] = useState(false)
5 const [sending, setSending] = useState(false)
6
7 async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
8 e.preventDefault()
9 setSending(true)
10
11 const data = Object.fromEntries(new FormData(e.currentTarget))
12 await fetch("https://formboost.app/f/YOUR_ENDPOINT_ID", {
13 method: "POST",
14 headers: { "Content-Type": "application/json" },
15 body: JSON.stringify(data),
16 })
17
18 setSending(false)
19 setSent(true)
20 }
21
22 if (sent) return <p style={{ color: "green" }}>Message sent! We'll be in touch.</p>
23
24 return (
25 <form onSubmit={handleSubmit} style={{ display: "flex", flexDirection: "column", gap: 12 }}>
26 <input type="text" name="name" placeholder="Name" required style={{ padding: "8px 12px", borderRadius: 6, border: "1px solid #ccc" }} />
27 <input type="email" name="email" placeholder="Email" required style={{ padding: "8px 12px", borderRadius: 6, border: "1px solid #ccc" }} />
28 <textarea name="message" rows={4} placeholder="Message" style={{ padding: "8px 12px", borderRadius: 6, border: "1px solid #ccc" }} />
29 <button type="submit" disabled={sending} style={{ padding: "10px 20px", background: "#0070f3", color: "#fff", border: "none", borderRadius: 6, cursor: "pointer" }}>
30 {sending ? "Sending…" : "Send"}
31 </button>
32 </form>
33 )
34}This version shows an inline success message instead of redirecting.