Astro Contact Form Without a Backend (2026)
Add a working contact form to any Astro site in minutes — no server, no API routes, no reCAPTCHA. Copy-paste HTML plus spam protection and email alerts.
The ShipMyForm team
· 3 min read
To add a contact form to an Astro site without a backend, point a normal HTML
<form> at a hosted form endpoint and let it handle the submission. Astro builds
to static files, so there's no server to receive the post yourself — a form backend
is the piece that receives it, filters spam, and emails you. Here's the whole thing:
---
// src/pages/contact.astro
---
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST">
<label>
Email
<input type="email" name="email" required />
</label>
<label>
Message
<textarea name="message" required></textarea>
</label>
<button type="submit">Send message</button>
</form>Replace YOUR_FORM_ID with the ID from your form backend and you have a working
contact form. That's the five-minute version. The rest of this guide covers success
handling, spam, and doing it with fetch if you want to stay on the page.
Don't want to hand-write the markup? Generate it — honeypot and Turnstile included —
with the free contact form generator, then paste the
result into your .astro page.
1. Create the form endpoint
You need a URL to send submissions to. With ShipMyForm, create a form and copy
its endpoint — it looks like https://shipmyform.com/f/abc123. Every field's name
attribute (email, message) becomes a field you receive.
2. Show a thank-you page
By default the browser follows the response to a thank-you page. Point it wherever
you like with a hidden _redirect field:
<form action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST">
<input type="hidden" name="_redirect" value="https://your-site.com/thanks" />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send message</button>
</form>Create src/pages/thanks.astro with a confirmation message and you're done — this
works with zero JavaScript, which is the Astro way.
3. Submit without leaving the page (optional)
If you'd rather show an inline success state, submit with fetch and ask for JSON
back. Astro ships almost no client JS, so add a tiny inline script:
<form id="contact" action="https://shipmyform.com/f/YOUR_FORM_ID" method="POST">
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send</button>
<p id="status" hidden>Thanks — we'll be in touch.</p>
</form>
<script>
const form = document.getElementById("contact");
form.addEventListener("submit", async (event) => {
event.preventDefault();
const res = await fetch(form.action, {
method: "POST",
body: new FormData(form),
headers: { Accept: "application/json" },
});
if (res.ok) {
form.reset();
document.getElementById("status").hidden = false;
}
});
</script>The Accept: application/json header is what makes the backend return
{ ok: true } instead of redirecting.
4. Block spam
Static contact forms get scraped and hit by bots, but you can stop most of them without a CAPTCHA. The simplest, zero-friction defense is a honeypot — a hidden field real people never fill. If it's filled, the submission is a bot.
Add a honeypot field the backend knows to check:
<!-- visually hidden; keep it out of the tab order -->
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off" style="display:none" />ShipMyForm checks the honeypot and rate-limits submissions automatically, and you can turn on Cloudflare Turnstile if a form gets targeted — no reCAPTCHA puzzles for your visitors.
Everything here is safe to ship in a static build — there are no API keys in the page. The form endpoint is public by design and only accepts submissions from your allowed domains.
5. Get notified
Submissions land in an inbox, and you can turn on an email notification so every message hits your inbox. From there, route to Slack, Google Sheets, or a webhook without touching your Astro code.
Why not an Astro API route?
Astro can run server endpoints if you add an adapter and switch to server output. That's real work — and you still have to write spam filtering, storage, and email yourself. For a contact form, a hosted backend keeps your site static and skips all of that. If you're weighing the trade-off, read what a form backend is and when you need one.
Next steps
- Harden it: stop contact form spam without reCAPTCHA
- Compare providers: Formspree alternatives
- Start free — 100 submissions a month, no credit card.
Frequently asked questions
- Can you have a contact form on an Astro site?
- Yes. Astro output is static by default, so you point a normal HTML form at a hosted form backend. The backend receives the submission and emails it to you — no server or API route needed.
- Do I need Astro server output (SSR) for a contact form?
- No. A hosted form backend works with a fully static Astro build. You only need SSR if you want to process the submission in your own server code.
- How do I stop spam on an Astro contact form?
- Add a hidden honeypot field and let the backend score submissions, then optionally enable Cloudflare Turnstile. ShipMyForm checks the honeypot and rate-limits submissions automatically.
Related guides
How to Stop Contact Form Spam Without reCAPTCHA
Honeypots, rate limiting, and Turnstile — layered spam defenses that beat reCAPTCHA without the puzzles.
What Is a Form Backend? (And When You Need One)
The plain-language definition, how form endpoints work, and when a hosted backend beats rolling your own.
ShipMyForm vs Formspree: An Honest 2026 Comparison
An honest look at ShipMyForm vs Formspree: free tiers, retention, spam, pricing, and a drop-in migration that is usually one URL change.