Guide
Add a contact form to a Hugo site
Hugo builds static HTML, so a form needs somewhere to POST. Put the endpoint in your site config once, render the form from a partial, and drop it into any template or markdown page with a shortcode.
Step 1: Get an endpoint
Create a form in the dashboard and copy your endpoint. Verify the email address you want submissions sent to.
Step 2: Put the endpoint in your config
One place to change it later beats hunting through templates:
# hugo.toml
[params]
formEndpoint = "https://forms.scrolltheory.media/f/YOUR_FORM_ID"
Step 3: Create the partial
<!-- layouts/partials/contact-form.html -->
<form action="{{ .Site.Params.formEndpoint }}" method="POST">
<label>Name
<input type="text" name="name" required>
</label>
<label>Email
<input type="email" name="email" required>
</label>
<label>Message
<textarea name="message" rows="5" required></textarea>
</label>
<!-- hidden spam honeypot: leave empty -->
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
style="position:absolute;left:-9999px" aria-hidden="true">
<button type="submit">Send message</button>
</form>
Use it in any template with {{ partial "contact-form.html" . }}.
Step 4: Optional shortcode for markdown pages
To place the form inside content files, wrap the partial in a shortcode:
<!-- layouts/shortcodes/contact-form.html -->
{{ partial "contact-form.html" . }}
Then write {{< contact-form >}} in any markdown page, on its own line.
Step 5: Build and test
Run hugo, deploy the public/ folder wherever you host, and submit a test. The submission appears in your dashboard and lands at your verified email with reply-to set to the sender. The honeypot field quarantines most bots, and anything flagged is held for review instead of deleted.
Get your endpoint
Create a form on the free plan and you get an endpoint to drop into any of the examples above. Every submission is stored and spam is quarantined rather than deleted, so a false positive never costs you a real lead.
More guides
- Build a contact form with AI and make it work
- Add a working contact form to any website
- Connect a React or Next.js form to a backend
- Connect a webhook to your form: Zapier, Slack, Discord
- Add a contact form to a Cloudflare Pages site
- Contact form for a static site, no backend needed
- Add a contact form to an Astro site