Skip to main content

Astro contact form without an API route or a server

By Maxime Branger · Published on

Keeping Astro static

With Astro, you can process a form in an API route, but that requires an adapter and server mode. If your site uses output: 'static' , AirMess avoids that change.

Step 1: the component

Create src/components/ContactForm.astro :

---
interface Props {
  formUrl?: string;
}
const { formUrl = import.meta.env.PUBLIC_AIRMESS_URL } = Astro.props;
---

<form id="contact-form" action={formUrl} method="POST">
  <label for="name">Name</label>
  <input id="name" name="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</button>
  <p id="contact-status" role="status"></p>
</form>

<script>
  const form = document.querySelector<HTMLFormElement>('#contact-form')!;
  const status = document.querySelector('#contact-status')!;

  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    const button = form.querySelector('button')!;
    button.disabled = true;
    status.textContent = 'Sending…';

    try {
      const res = await fetch(form.action, { method: 'POST', body: new FormData(form) });
      if (!res.ok) throw new Error(String(res.status));
      form.reset();
      status.textContent = 'Thank you, your message has been sent.';
    } catch {
      status.textContent = "Sending failed. Please try again in a moment.";
    } finally {
      button.disabled = false;
    }
  });
</script>

Step 2: the environment variable

In .env :

PUBLIC_AIRMESS_URL=https://airmess.fr/api/submit/YOUR_TOKEN

The PUBLIC_ prefix is required for Astro to expose it at build time. The URL is not a secret, since it appears in the HTML, but the variable lets you use a different URL in staging.

Step 3: use it

---
import ContactForm from '../components/ContactForm.astro';
---
<h1>Contact</h1>
<ContactForm />

Astro automatically processes and bundles the component's <script> : no extra configuration.

The full code of this tutorial is available on GitHub.