The Best Form Backends for Hugo and Jekyll in 2026

8 min read
Static Forms Team

Hugo and Jekyll generate static sites with no server behind them. That's exactly why they're fast and cheap to host — and exactly why a plain <form> has nowhere to send its data. To make contact forms work, you point them at a form backend: a hosted endpoint that receives the submission, blocks spam, and emails it to you (or forwards it onward).

There are a handful of ways to do this, and they're not equal for static sites built with Hugo or Jekyll. This guide walks through the realistic options, what each is good and bad at, and how to pick.

What a form backend actually has to do

Before comparing options, it helps to be clear about the job. For a Hugo or Jekyll site, a good form backend needs to:

  • Accept a submission from a purely static page — no server-side code on your side.
  • Filter spam without forcing a clunky CAPTCHA on every visitor.
  • Deliver reliably to email, with a usable reply-to address.
  • Optionally route data elsewhere — a spreadsheet, Slack, a webhook.
  • Not lock you in — your form is just HTML posting to a URL, so switching should be trivial.
Which approach fits your static site?
🔌
Hosted form backend (recommended)
Post HTML to an endpoint. Zero server, spam filtering and email built in. Best fit for Hugo & Jekyll.
🏗️
Host-bundled forms
Convenient if you stay on one host — but ties your form to that platform.
⚙️
Roll your own serverless function
Maximum control, but you own deliverability, spam, and maintenance.
📧
mailto: link
No backend at all — but it's not really a form. Avoid for anything real.

Option 1: A hosted form backend (best fit for most sites)

This is the approach built for exactly this problem. You add a normal HTML form to your Hugo partial or Jekyll include, set the action to a hosted endpoint, and you're done. The service receives the POST, screens it for spam, and emails you the message.

Why it suits Hugo and Jekyll: there's nothing to deploy or maintain on your end, it works identically on every host, and your form stays portable — it's just markup pointing at a URL.

Static Forms is built around this model. A working form is a single HTML block:

HTML
<form action="https://api.staticforms.dev/submit" method="POST">
  <input type="hidden" name="apiKey" value="YOUR_API_KEY_HERE" />
  <input type="hidden" name="replyTo" value="@" />
  <input type="text" name="name" required />
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>
  <input type="text" name="honeypot" style="display:none" tabindex="-1" />
  <button type="submit">Send</button>
</form>

The honeypot field catches the bulk of spam bots without a CAPTCHA, replyTo="@" makes the submitter's address your reply-to, and there's a free tier to start. You can also forward submissions to a Google Sheet, Slack, or any endpoint via webhooks. Other hosted backends in this category include Formspree, Getform, Basin, and Web3Forms — the model is similar across them, so the differentiators are spam handling, deliverability, integrations, and pricing.

Best for: almost any Hugo or Jekyll site. It's the lowest-effort option that still does the job properly.

Option 2: Forms bundled with your host

Some static hosts bundle a form-handling feature — Netlify Forms is the best-known example, and Cloudflare and others have their own takes. You add an attribute or special markup, and the host intercepts submissions during the build or at the edge.

The upside: it's convenient if you're already on that host and never plan to leave. The catch: your form is now coupled to the platform. Move your Hugo or Jekyll site to a different host and the form stops working until you rewire it. There are also usually tight limits on submissions before you hit a paid tier.

Best for: sites firmly committed to one host, with light form volume.

Option 3: Your own serverless function

If you want total control, you can write a small serverless function — on Vercel, Cloudflare Workers, AWS Lambda, or similar — that receives the POST, sends an email through a provider, and screens for spam. Your Hugo or Jekyll form posts to that function's URL.

The upside: you own the whole pipeline and can do anything. The cost: you now own everything — email deliverability (and the SPF/DKIM headaches that come with it), spam filtering, error handling, and ongoing maintenance. For a contact form, that's a lot of surface area to babysit.

Best for: teams with specific custom logic and the appetite to maintain it.

The zero-backend "solution" is a mailto: link or a form with action="mailto:...". It opens the visitor's email client instead of submitting anywhere.

In practice it's a poor experience: it depends on the visitor having a configured desktop mail client, exposes your address to scrapers, and captures nothing structured. It's fine as a fallback link, not as your contact form.

Best for: a quick "email me" link — not a real contact form.

Feature comparison at a glance

Here's how the four approaches stack up on the things that actually matter for a Hugo or Jekyll site:

Hosted backend Host-bundled Own serverless mailto:
Server code to maintain None None Yes — you own it None
Works on any host ❌ tied to host
Built-in spam filtering Partial You build it
Email delivery handled You configure SPF/DKIM N/A
Route to Sheets / Slack / webhooks Limited You build it
Captures structured data
Setup time Minutes Minutes Hours+ Minutes
Portable (just HTML) Mostly

The pattern is clear: a hosted backend gives you the least to maintain while still ticking every box that matters. The host-bundled option trades portability for convenience, and rolling your own trades time and maintenance for control.

What about spam?

Spam is the number-one reason a naive contact form becomes unusable, so it deserves its own look. A static site can't run server-side filtering on its own, which leaves three layers worth understanding:

  • Honeypot fields. A hidden input that humans never fill but bots do. It's invisible to visitors, requires no extra clicks, and catches the bulk of automated spam. Every example in our Hugo and Jekyll tutorials includes one.
  • Server-side screening. A good hosted backend scores submissions and drops obvious junk before it ever reaches your inbox — something a mailto: link or a bare serverless function won't do unless you build it.
  • CAPTCHA, only when needed. If sophisticated spam slips through, you can add a challenge like reCAPTCHA, Cloudflare Turnstile, or Altcha. The trick is to treat it as a fallback rather than a default, since every CAPTCHA adds friction for real visitors.

The right order is honeypot first, server-side screening always, and a CAPTCHA only if the first two aren't enough.

How to choose

For the large majority of Hugo and Jekyll sites, a hosted form backend (Option 1) is the right answer: it matches the static-site model exactly, requires no infrastructure, and keeps your form portable across hosts. Reach for a host-bundled option only if you're locked to one platform anyway, or a custom serverless function only when you genuinely need custom logic and will maintain it.

If you want to see the hosted approach end to end, we have step-by-step tutorials for Jekyll on GitHub Pages and Hugo, plus a general primer on sending form data without a server.

Switching is painless

One underrated advantage of the hosted approach: there's almost nothing to migrate. Your form is just an HTML <form> with an action URL and a few hidden fields. Moving from one backend to another — or moving your whole Hugo or Jekyll site to a new host — means changing the endpoint URL and the key, and nothing else. Compare that to a host-bundled solution, where leaving the host means rebuilding form handling from scratch, or a custom serverless function, where the whole pipeline moves with you. Keeping the form as portable markup is the safest long-term bet for a static site.

Frequently asked questions

Do I need to know any backend programming?
No. With a hosted backend your only job is to write the HTML form and point it at an endpoint. The server-side work is handled for you.

Will a form backend slow down my static site?
No. The form is static HTML that loads with the page. The backend only does work when someone actually submits, and that request goes directly from the visitor's browser to the API — your site stays as fast as ever.

Can I use the same backend for Hugo and Jekyll?
Yes. The approach is identical across static site generators — only the templating (a Hugo partial vs. a Jekyll include) differs. The form markup and endpoint are the same.

Is there a free option?
Yes — Static Forms has a free plan that's plenty for a typical contact form. You can see the limits and paid tiers on the pricing page.

Wrapping up

A static site doesn't mean a static contact page. The cleanest way to make forms work on Hugo and Jekyll is to keep the form as plain HTML and let a hosted backend do the server-side work — so you keep the speed and simplicity that made you choose a static generator in the first place.

Start free with Static Forms and have a working form on your site in a few minutes.