Skip to content

Integration guide · Hugo

Add a contact form to your Hugo site — no server required

Hugo builds pure static HTML — there is no server to receive a form POST. That's exactly what a form backend is for: point your form's action at a PostTo endpoint and submissions are delivered to your inbox, with spam filtering and a searchable dashboard, while your site stays fully static.

No JavaScript, no theme changes, no build configuration. One partial template and you're done.

Free plan, no credit card required.

Three steps, a few minutes

1

Create an endpoint

Sign up free, create an endpoint in the dashboard, and set your destination email. You'll get an endpoint URL right away.

2

Add a form partial

Create layouts/partials/contact-form.html with the form below and include it anywhere with {{ partial "contact-form.html" . }}.

3

Build and deploy

hugo builds your site as usual — GitHub Pages, Cloudflare Pages, S3, anywhere. Submissions land in your inbox and dashboard.

The code

Replace YOUR_TOKEN with the endpoint URL from your dashboard.

layouts/partials/contact-form.html
<form action="https://postto.dev/api/v1/send/YOUR_TOKEN" method="POST">
  <label for="name">Name</label>
  <input type="text" id="name" name="name" required>

  <label for="email">Email</label>
  <input type="email" id="email" name="email" required>

  <label for="message">Message</label>
  <textarea id="message" name="message" required></textarea>

  <!-- Honeypot: bots fill this in, humans never see it -->
  <input type="text" name="_hp" tabindex="-1" autocomplete="off" style="display:none">

  <!-- Where to send the visitor after a successful submission -->
  <input type="hidden" name="_next" value="https://yoursite.com/thanks/">

  <button type="submit">Send</button>
</form>

Good to know

Works with any theme

The form is plain HTML, so it inherits your theme's styling. Keep it in a partial so you can include it on the contact page, in a footer, or via a shortcode.

Success page

Create a content/thanks.md page and point the hidden _next field at it. Or leave _next out and PostTo shows a hosted success page you can customise per endpoint.

Spam protection is already wired in

The hidden _hp field is a honeypot — humans never see it, bots fill it in, and PostTo silently discards those submissions. Server-side baseline filtering (heuristics and optional AI classification) runs on every submission after that, so you don't need a CAPTCHA to start.

Frequently asked questions

Does Hugo need any plugins or config for this?
No. Hugo just renders the HTML; the form posts directly from the visitor's browser to PostTo. There is nothing to install and no build step to change.
Can I use this in a shortcode instead of a partial?
Yes — put the same markup in layouts/shortcodes/contact-form.html and drop the shortcode into any content file. Partials suit templates; shortcodes suit Markdown content.
How do I stop spam without a CAPTCHA?
Include the hidden _hp honeypot field shown above. PostTo also runs first-party heuristic filtering on every submission, and you can enable AI classification per endpoint. Cloudflare Turnstile is supported if you want a visible challenge.
What does it cost?
The free plan includes 50 submissions per month with the full dashboard — no credit card required. Paid plans start at $9/month.

Add a form to your Hugo site today

Create an endpoint, paste the snippet, and see your first submission in the dashboard — all on the free plan.

Try PostTo free