Beginner5 minUpdated Mar 27, 2026

How to Add a Contact Form to Gatsby

Add a working contact form to your Gatsby site with React components and FormsList. No serverless functions or Gatsby Functions needed.

TL;DR

To add a contact form to a Gatsby site, create a React component that submits to `https://formslist.com/f/your-form-id`. Since Gatsby generates static HTML, a form backend like FormsList handles submissions without needing serverless functions.

By Vaibhav Jain·Published March 27, 2026

Prerequisites

  • A Gatsby project
  • A FormsList account (free)
  • Basic knowledge of React
1

Create a FormsList form endpoint

Sign up for a free FormsList account and create a new form. Copy the endpoint URL from your dashboard.

// Your endpoint will look like this:
// https://formslist.com/f/YOUR_FORM_HASH
2

Create the contact form component

Create a React component in your Gatsby project. Gatsby uses React, so the pattern is the same as a standard React form: useState for status management and fetch for submission.

// src/components/ContactForm.jsx
import React, { useState } from "react"

export default function ContactForm() {
  const [status, setStatus] = useState("idle")

  async function handleSubmit(e) {
    e.preventDefault()
    setStatus("sending")

    const form = e.currentTarget
    const data = new FormData(form)

    try {
      const res = await fetch("https://formslist.com/f/YOUR_FORM_HASH", {
        method: "POST",
        body: data,
      })

      if (res.ok) {
        setStatus("sent")
        form.reset()
      } else {
        setStatus("error")
      }
    } catch {
      setStatus("error")
    }
  }

  return (
    <form onSubmit={handleSubmit} style={{ maxWidth: 480 }}>
      <div style={{ marginBottom: "1rem" }}>
        <label htmlFor="name" style={{ display: "block", fontWeight: 600 }}>Name</label>
        <input type="text" id="name" name="name" required style={{ width: "100%", padding: "0.5rem" }} />
      </div>
      <div style={{ marginBottom: "1rem" }}>
        <label htmlFor="email" style={{ display: "block", fontWeight: 600 }}>Email</label>
        <input type="email" id="email" name="email" required style={{ width: "100%", padding: "0.5rem" }} />
      </div>
      <div style={{ marginBottom: "1rem" }}>
        <label htmlFor="message" style={{ display: "block", fontWeight: 600 }}>Message</label>
        <textarea id="message" name="message" rows={4} required style={{ width: "100%", padding: "0.5rem" }} />
      </div>
      <button type="submit" disabled={status === "sending"}
        style={{ padding: "0.6rem 1.5rem", background: "#2563eb", color: "#fff", border: "none", borderRadius: 4, cursor: "pointer" }}>
        {status === "sending" ? "Sending..." : "Send Message"}
      </button>
      {status === "sent" && <p style={{ color: "green" }}>Message sent successfully!</p>}
      {status === "error" && <p style={{ color: "red" }}>Something went wrong. Please try again.</p>}
    </form>
  )
}
3

Add the form to a Gatsby page

Import the ContactForm component into a Gatsby page. Gatsby pages live in the src/pages/ directory and are automatically routed based on filename.

// src/pages/contact.jsx
import React from "react"
import Layout from "../components/Layout"
import ContactForm from "../components/ContactForm"

export default function ContactPage() {
  return (
    <Layout>
      <h1>Contact Us</h1>
      <p>Fill out the form below and we will get back to you within 24 hours.</p>
      <ContactForm />
    </Layout>
  )
}

export function Head() {
  return <title>Contact Us</title>
}
4

Deploy and test

Build your Gatsby site with `gatsby build` and deploy to your hosting provider (Netlify, Vercel, Gatsby Cloud, etc.). Submit a test message and verify it appears in your FormsList dashboard. Enable email notifications and integrations.

Frequently Asked Questions

Do I need Gatsby Functions for a contact form?

No. Gatsby Functions run server-side code, but with FormsList handling the backend, you can keep your site fully static. No serverless functions needed.

Does this work with Gatsby's static site generation?

Yes. The form component renders as HTML during the build, and the client-side JavaScript handles submission via fetch. FormsList processes the data externally.

Can I use Gatsby plugins for forms instead?

Plugins like gatsby-plugin-netlify add form handling tied to specific hosts. FormsList works on any hosting provider and gives you a dashboard for managing submissions, notifications, and integrations.

Ready to collect form submissions?

200 free submissions a month and a live endpoint in 30 seconds. No server, no credit card, just point your form at it.

Sign up with emailView pricing