The Complete Guide to Contact Forms on JAMstack Sites
JAMstack (JavaScript, APIs, Markup) is an architecture where websites are pre-built as static files and served from a CDN. Frameworks like Next.js, Gatsby, Hugo, Jekyll, Astro, and Nuxt all follow this pattern to deliver fast, secure websites. The tradeoff is that there is no server running to process form submissions, send emails, or store data.
This means every JAMstack site that needs a contact form faces the same question: how do you handle form submissions without a backend?
Your Options for JAMstack Forms
Serverless Functions
You can write your own serverless function (AWS Lambda, Vercel Functions, Netlify Functions) to process submissions. This gives you full control but requires:
- Writing and maintaining backend code
- Setting up an email service (SES, SendGrid, etc.)
- Implementing spam protection yourself
- Managing environment variables and deployment
- Monitoring for failures
For a simple contact form, this is a lot of infrastructure to build and maintain.
Form Backend Services
A form backend service provides an API endpoint that handles everything for you: receiving submissions, sending emails, filtering spam, and storing data. You point your HTML form at the service's URL and it takes care of the rest.
This is the approach we recommend for most JAMstack sites. It works with any framework, any hosting provider, and requires zero backend code.
Why Static Forms for JAMstack
Static Forms is designed specifically for this use case. Here is why it works well with JAMstack:
- Zero backend code — Add an action URL to your form and you are done
- Works with any host — Vercel, Netlify, GitHub Pages, Cloudflare Pages, AWS S3, or any CDN
- Works with any framework — HTML forms are universal across all JAMstack frameworks
- Free tier — 500 submissions per month at no cost
- Spam protection — reCAPTCHA v2, reCAPTCHA v3 (invisible), and Altcha (privacy-first CAPTCHA)
- Pro features — File uploads, webhooks, auto-responders, submission dashboard, and CSV export
Universal HTML Form
This form works with every JAMstack framework because it uses standard HTML:
Replace YOUR_API_KEY_HERE with your API key from the Static Forms dashboard. This form will work on any static site — just paste it into your HTML.
For a JavaScript-powered version with inline success/error messages (no page redirect), submit via fetch instead:
Framework-Specific Notes
The HTML form above works everywhere, but each framework has its own conventions for components and environment variables. Here are quick pointers for the most popular JAMstack frameworks:
Next.js
Use a React component with useState for form state and fetch for submission. Store your API key in NEXT_PUBLIC_STATIC_FORMS_KEY. See our full Next.js integration guide.
Gatsby
Gatsby sites can use the same React component approach as Next.js. We have a dedicated tutorial: Using Static Forms with Gatsby.
Astro
Astro generates static HTML by default, so the plain HTML form works perfectly. For client-side interactivity, use an Astro <script> tag. See our Astro documentation.
Nuxt
Use a Vue component with Composition API or Options API. Store your key in NUXT_PUBLIC_STATIC_FORMS_KEY and access it via useRuntimeConfig(). See our Nuxt.js guide.
Hugo
Hugo generates static HTML, so use the plain HTML form directly in your templates. Place the form in a partial (layouts/partials/contact-form.html) and include it in any page.
Jekyll
Similar to Hugo, use the HTML form directly in your Liquid templates. Add it to a layout or include file (_includes/contact-form.html).
Features That Matter for JAMstack
When choosing a form backend for your JAMstack site, consider these features:
Spam Protection
Bots target every form on the internet. Static Forms gives you three layers of protection:
- Honeypot field (free) — A hidden field that catches basic bots
- reCAPTCHA v2/v3 (v3 on Pro) — Google's bot detection, including an invisible option
- Altcha (Pro) — A privacy-first CAPTCHA that works without external tracking, ideal for GDPR compliance
File Uploads
Accept file attachments (PDFs, images, documents) directly through your form. Files are included in the email notification and stored in your dashboard. Available on Pro and Advanced plans.
Webhooks
Trigger external services when a form is submitted. Send data to Slack, Zapier, your CRM, or any service that accepts HTTP requests. Available on Pro and Advanced plans.
Auto-Responders
Automatically send a confirmation email to the person who submitted the form. Customize the subject and body to match your brand. Available on Pro and Advanced plans.
Get Started
Adding a contact form to your JAMstack site takes less than five minutes with Static Forms. Paste the HTML form into your site, add your API key, and you are receiving submissions immediately.
Sign up for Static Forms to get your free API key and start with 500 submissions per month. No credit card required.
For more integration examples, check out our tutorials for React, Next.js, Gatsby, and Nuxt.js.
Related Articles
How to Add a Contact Form to Your Astro Website
Step-by-step tutorial for adding a working contact form to Astro sites using Static Forms — no backend required.
How to Add a Contact Form to GitHub Pages
Learn how to add a fully functional contact form to your GitHub Pages site without any backend code. Complete tutorial with working examples.
Adding Contact Forms to Static Websites Guide
Learn how to easily add fully functional contact forms to your static website without backend code using a form endpoint service.