Integration guide · Framer
A Framer contact form that emails you — with one small code component
Framer's built-in forms are quick to style and can email you, but how spam is handled and where submissions are stored is Framer's call. When you need a dashboard to review held spam, EU hosting, or the same form backend across every site you build, you want the form to post somewhere you control.
A small Framer code component does that: paste it in once, drop it on any page, and set the endpoint URL in the properties panel. Submissions post from the visitor's browser straight to PostTo, which filters spam, emails you, and logs everything to a searchable dashboard.
Free plan, no credit card required · Updated
Three steps, a few minutes
Create an endpoint
Sign up free, create an endpoint in the dashboard, and set your destination email. You'll get an endpoint URL right away.
Add the code component
In Framer, create a new code component from the Assets panel, replace its contents with the snippet below, and save. It appears in your assets like any other component.
Drop it on a page and publish
Place the component, paste your endpoint URL into its Endpoint URL property, and publish. Submit the form from the live site — the email lands in your inbox and the dashboard.
The code
Paste it as-is — set your endpoint URL in the component's Endpoint URL property, not in the code.
import { useState } from "react"
import { addPropertyControls, ControlType } from "framer"
export default function PostToForm(props) {
const [status, setStatus] = useState("idle")
async function handleSubmit(event) {
event.preventDefault()
const payload = Object.fromEntries(new FormData(event.currentTarget))
const response = await fetch(props.endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(payload),
})
setStatus(response.ok ? "sent" : "error")
}
if (status === "sent") {
return <p>{props.successMessage}</p>
}
return (
<form onSubmit={handleSubmit} style={{ display: "grid", gap: 12, width: "100%" }}>
<input type="text" name="name" placeholder="Name" required />
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" rows={5} required />
{/* Honeypot: bots fill this in, humans never see it */}
<input type="text" name="_hp" tabIndex={-1} autoComplete="off" style={{ display: "none" }} />
<button type="submit">Send</button>
{status === "error" && <p>Something went wrong. Please try again.</p>}
</form>
)
}
addPropertyControls(PostToForm, {
endpoint: {
type: ControlType.String,
title: "Endpoint URL",
defaultValue: "https://postto.dev/api/v1/send/YOUR_TOKEN",
},
successMessage: {
type: ControlType.String,
title: "Success message",
defaultValue: "Thanks — we'll be in touch.",
},
})
Good to know
One component, every site
The endpoint URL is a property, so the same component works across pages and projects — paste a different endpoint per site, each with its own destination email, without touching the code.
Token only — never signed mode here
The request runs in the visitor's browser, so use the plain endpoint URL with its token. Never enable signed mode for this endpoint — the HMAC secret would have to ship inside your published site, visible to anyone.
Spam protection is already wired in
The hidden _hp field is a honeypot — humans never see it, bots fill it in, and PostTo silently discards those submissions. Server-side baseline filtering (heuristics and optional AI classification) runs on every submission after that, so you don't need a CAPTCHA to start.
From the docs
Frequently asked questions
- Do I need to know React to use this?
- No. Paste the component as-is and set the Endpoint URL property — nothing in the code needs editing. Style it by wrapping it in a Framer frame, or adjust the inline styles if you want to go further.
- Can I add more fields?
- Yes — add another input with a name attribute and it arrives in the email and dashboard automatically. PostTo accepts any fields; name, email, and message are just the ones it uses for the sender, Reply-To, and body.
- Does it show a success message without leaving the page?
- Yes. The component submits with fetch and swaps the form for the Success message property when PostTo accepts the submission, so the visitor never leaves your Framer page.
- What does it cost?
- The free plan includes 50 submissions per month with the full dashboard — no credit card required. Paid plans start at $9/month.
Add a form to your Framer site today
Create an endpoint, paste the snippet, and see your first submission in the dashboard — all on the free plan.
Try PostTo free