Get the next one in your inbox.
One email when we publish something worth reading. No spam — appropriately enough, we'd know.
Add a working contact form to an Astro site with a plain .astro component and no client-side JavaScript — just point the form at a FormBridge endpoint.

Get an instant summary, key takeaways, action items, and answers to your questions about this article.
Add a plain <form> to any Astro component or page and set its action to your FormBridge endpoint URL — Astro ships zero JavaScript by default, so no client directive or hydration is needed for the form to submit and trigger an email notification.
Astro ships zero JavaScript to the client by default — that's the whole pitch of the framework. A <form> element doesn't need a client directive, a signal, or an island to submit; the browser already knows how to POST a form to a URL. The only decision you're making is what URL to point it at.
For a contact form, that URL can be a FormBridge endpoint instead of a route you'd have to build and maintain yourself.
---
// src/components/ContactForm.astro
---
<form action="https://app.formbridge.ai/api/forms/fb_8h2k9p" method="POST" class="contact-form">
<label for="full-name">Full name</label>
<input id="full-name" name="full-name" type="text" required />
<label for="email">Email</label>
<input id="email" name="email" type="email" required />
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<button type="submit">Send message</button>
</form>
<style>
.contact-form {
display: grid;
gap: 0.75rem;
max-width: 480px;
}
</style>
Drop that into any .astro page or layout and it's done — no client:load, no useState, no hydration budget spent on a form that doesn't need any interactivity.
The browser does a normal full-page POST. FormBridge receives it, runs it through spam scoring, and — assuming it passes — emails your recipient list and, if configured, sends an autoresponder back to whoever filled it in. The response is JSON ({ "ok": true, "id": "sub_..." }), so without any JavaScript the visitor's browser will navigate to that raw JSON after submitting.
For an internal tool that's often fine as-is. For a public site, most teams eventually add a few lines of fetch() in a <script> tag to intercept the submit and swap in a "thanks, we got it" message instead — but that's a UX polish step, not a requirement. The form works, and the email arrives, with zero JS shipped.
Nothing here changes for spam protection — it's configured on the FormBridge side, per form, not in your Astro code. Turn on a honeypot field or CAPTCHA from the form's Settings → Spam Protection tab and every submission through this same endpoint gets the extra layer, with no component changes required.
No. A plain HTML form only needs JavaScript for behaviors like intercepting submit or showing inline validation; submitting to an external endpoint like FormBridge works fine with a static, non-hydrated form.
The browser does a full-page POST and navigates to whatever the endpoint returns. FormBridge returns a small JSON response, so without JS the visitor will briefly see that JSON page after submitting.
Yes — CAPTCHA, honeypot fields, and domain allow-lists are configured on the form backend side (in FormBridge's Settings → Spam Protection), not in the Astro component, so none of it requires client-side code.
One email when we publish something worth reading. No spam — appropriately enough, we'd know.