Blog
Migrating from Formspree to Formhook: the ten-minute guide
· 3 min read
The best thing about the form-backend category is that switching providers is trivial by design: your site's only integration point is one URL. Here's the complete migration, including the parts people forget.
(Why migrate at all? The honest comparison - pricing, retention, EU hosting - lives on the Formhook vs Formspree page. This guide assumes you've decided.)
Step 1: export your existing submissions
If you're on a paid Formspree plan, export your submission history first - per their pricing page, export is included from the Personal plan up. Check your form's submissions view for the export option and download everything before touching anything else. If you're on their free plan, copy anything you need manually; their free tier is positioned for testing, so ideally there's little production data in it.
Keep this export regardless of where you land - provider-agnostic backups of lead data are just good hygiene.
Step 2: create the Formhook form
Sign up, create a form, and copy its key. Two settings to configure while you're there:
- CORS allowlist - add your site's domain(s), including the
wwwvariant if you serve both. - Turnstile - if you had CAPTCHA-style protection before, enable Turnstile now so protection is continuous through the switch. Honeypot and rate limiting are already on.
Step 3: the one-line change
- <form action="https://formspree.io/f/xyzabcde" method="POST">
+ <form action="https://formhook.app/f/fh_your-key" method="POST">Field names don't need to change - both services accept standard form-encoded POSTs, and Formhook also takes JSON and multipart. If you used fetch/AJAX, the same one-line swap applies to the URL in your code.
Things to grep for so you catch every instance: the old URL in components, environment variables like FORM_ENDPOINT, and any hardcoded endpoint in per-page templates. Multi-form sites: Formhook's free tier includes multiple forms, so map each old form to its own key rather than merging - per-form notifications and settings stay clean that way.
Step 4: test from the deployed site
Deploy, then submit a real test from the production URL, not localhost - that's the only place CORS, DNS, and TLS are all exercised together. Confirm three things: the success state shows in the browser, the submission appears in your Formhook dashboard, and the notification arrives on your device. Run the full pre-launch checklist while you're at it.
Step 5: decommission the old form
Leave the old Formspree form live for a few days as a safety net, then disable it once you've confirmed submissions are flowing to Formhook. Keep your export archived. That's the entire migration - one attribute, a couple of settings, and a test. The reason it's this easy is the same reason leaving any form backend is easy: your site depends on a single URL, not a lock-in.
Ship a working form in one line
EU-hosted, submissions kept forever, push notifications on every tier.
Start freeNo credit card · read the docs
Keep reading
- What is a form backend? (And when you need one)A form backend receives, stores, and forwards your website's form submissions so you don't run a server. Here's how they work and when you need one.
- Contact form testing: the pre-launch checklistA broken contact form fails silently and costs leads for weeks. The 15-minute pre-launch checklist: happy path, validation, spam, mobile, and notifications.
- Contact form spam: honeypots, rate limits & TurnstileHow form spam actually works and the three layers that stop it: honeypot fields, rate limiting, and Cloudflare Turnstile - without punishing real visitors.