Contact forms for static sites

    GitHub Pages, Cloudflare Pages, Netlify, Vercel, S3 — any host that only serves files

    Reviewed by Ritu Fadadu · Last reviewed

    Why a static site cannot receive a form

    A static site is a folder of files. The host sends HTML, CSS and JavaScript to the browser and runs nothing when a visitor submits a form — so a form whose action points at your own site has nowhere to go, and a mailto: link only opens the visitor's email app.

    One form endpoint instead

    Point the form's action at a Formboost endpoint. The form stays plain HTML on your static host; Formboost receives each submission, screens it for spam, stores it and sends it to your inbox or team chat. No serverless function, no PHP, no build step.

    Formboost is a form backend: the form endpoint receives the submission, screens it for spam, stores it and delivers it — the same for a static site as for any other frontend.

    Setup in 5 Steps

    1

    Create a free Formboost form and copy its endpoint ID

    2

    Paste the form into any page of your static site

    3

    Replace YOUR_ENDPOINT_ID, and set _redirect to a thank-you page on the same site

    4

    Deploy as usual — nothing about your host or build changes

    5

    Submit once from the live site and check the submission in your dashboard

    Code Example

    <form action="https://formboost.app/f/YOUR_ENDPOINT_ID" method="POST">
      <label for="name">Name</label>
      <input id="name" name="name" type="text" autocomplete="name" required>
    
      <label for="email">Email</label>
      <input id="email" name="email" type="email" autocomplete="email" required>
    
      <label for="message">Message</label>
      <textarea id="message" name="message" rows="5" required></textarea>
    
      <!-- Honeypot: hidden from people, filled in by bots -->
      <div aria-hidden="true" style="position:absolute;left:-9999px">
        <input name="_honey" type="text" tabindex="-1" autocomplete="off">
      </div>
    
      <!-- Back to your own site afterwards: https, same site as this page -->
      <input type="hidden" name="_redirect" value="https://www.example.com/thanks.html">
    
      <button type="submit">Send</button>
    </form>

    Static sites: the details

    Which hosts this covers

    Any host that serves your site as files. The form is ordinary HTML in your pages, and the browser posts it straight to formboost.app, so the host is never involved in the submission. Some of these hosts can also run functions; a contact form does not need one.

    HostWhat to know
    GitHub PagesServes files from a repository; github.io sites are HTTPS. Step-by-step: contact form on GitHub Pages.
    Cloudflare PagesStatic assets by default. Preview deployments get their own address, so _redirect falls back there — see below.
    NetlifyHas its own form handling for sites hosted there; a Formboost form works the same on any host. How they compare.
    VercelStatic output needs no API route for the form. Preview URLs differ from production — see below.
    Amazon S3 / CloudFrontFiles only. Serve the site over HTTPS through CloudFront so your _redirect page can be https.
    Firebase HostingFiles only unless you add functions; the form needs none.

    Static site generators

    A generator builds the same kind of folder of files, so the form is the same everywhere — what changes is where you put it. Each guide shows the idiomatic place in that generator:

    • •Jekyll — in a page or an _includes partial; the endpoint can live in _config.yml.
    • •Astro — in an .astro component, as plain HTML or with a small script.
    • •Eleventy — in a template or include.
    • •Gatsby — a React component posting with fetch().
    • •Next.js static export — plain HTML or fetch(); Server Actions need a server, so a static export cannot use them.
    • •Hugo — put the form in a partial under layouts/partials/ and include it where you need it; the HTML is exactly the example above.

    Sending visitors back to your own page

    A plain HTML form is answered with a redirect. By default that is Formboost's thank-you page; add a hidden _redirect field and it is yours. The address must be https:// and on the same site as the page the form is on (the host must match exactly, so www. counts) — that rule is what stops anyone using the endpoint to send people to a site of their choosing.

    Two consequences on static hosts. Testing from localhost lands on Formboost's page, because localhost is not your site. And preview deployments — a pull-request preview on Netlify, Vercel or Cloudflare Pages — have their own address, so a _redirect that names your production domain falls back there too. On the live domain it works. If you want previews to redirect as well, set the field from the page itself:

    <input type="hidden" name="_redirect" id="redirect">
    <script>
      document.getElementById("redirect").value = location.origin + "/thanks.html";
    </script>

    Plain HTML or fetch()?

    Plain HTML needs no JavaScript and works on every host and every builder. If you would rather keep the visitor on the page, submit with fetch(): send the fields as JSON with Accept: application/json and you get a 202 back instead of a redirect. Do not pass new FormData(form) straight to fetch() — that sends a multipart body, which the endpoint refuses with 415. The HTML form generator writes either version for you.

    Spam on a static site

    A form on a static site has the same visible endpoint as any other form, so spam protection happens on Formboost's side, with no CAPTCHA for your visitors:

    • •A hidden _honey field catches bots that fill in every input. The submission is kept, marked as spam, and never forwarded.
    • •Every submission is screened: heuristics on the Free plan, with AI deciding the borderline cases on Starter and reading every submission on Pro and above — how it works.
    • •Each IP address is rate-limited, so a script cannot flood your inbox.

    What the free plan covers

    10 forms and 500 submissions a month, email notifications, and one Slack, Discord or Telegram destination per form — no card and no expiry. Submissions are stored in your dashboard and export to CSV. Webhooks, Google Sheets, Zapier, n8n and Auto Reply start on Starter. The form accepts text, choices, dates and links; it does not take file uploads.

    Keep going

    Frequently Asked Questions

    Common questions about using Formboost with a static site

    Do I need a serverless function for a contact form on a static site?

    No. The form posts straight to your Formboost endpoint, which does the server-side work. Hosts like Netlify, Vercel and Cloudflare Pages can run functions, but a contact form does not need one.

    Does it work on GitHub Pages?

    Yes. GitHub Pages only serves files, which is exactly the case Formboost is built for: the form is plain HTML in your repository and posts to your endpoint. The GitHub Pages guide walks through a user site, a project site and a custom domain.

    Why does my redirect land on Formboost's thank-you page?

    The _redirect address must be https and on the same site as the page that submitted the form. A test from localhost or a preview deployment has a different address, so it falls back to Formboost's page. On your live domain it works.

    Is it a problem that the endpoint is visible in my HTML?

    No. A form's action is always visible; the endpoint is public by design and there is no key to hide. Every submission is screened for spam, a hidden honeypot catches simple bots, and each IP address is rate-limited.

    What does it cost?

    The Free plan covers 10 forms and 500 submissions a month, with email notifications and one Slack, Discord or Telegram destination per form, and no card. Webhooks, Google Sheets, Zapier, n8n and Auto Reply start on Starter.

    Start building with Formboost on a static site

    It takes less than a minute to set up. No credit card required.