← All guides

Add form notifications to an Astro site

This guide shows you how to add a contact form to an Astro site that sends submissions to your email via Form Alert. Works with static and SSR modes.

Prerequisites

Option 1: Plain HTML form (no JS)

Astro components render as static HTML by default, so a standard form POST works without any client-side JavaScript.

src/pages/contact.astro
---
// src/pages/contact.astro
---

<html lang="en">
  <body>
    <h1>Contact us</h1>

    <form
      action="https://api.form-alert.com/v1/submit"
      method="POST"
    >
      <input
        type="hidden"
        name="access_key"
        value="YOUR_ACCESS_KEY"
      />

      <label for="name">Name</label>
      <input type="text" name="name" id="name" required />

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

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

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

Option 2: AJAX submission with a script

For a smoother experience without page reloads, add a <script> tag to handle the submission with JavaScript.

src/pages/contact.astro
---
// src/pages/contact.astro
---

<html lang="en">
  <body>
    <h1>Contact us</h1>

    <form id="contact-form">
      <input
        type="hidden"
        name="access_key"
        value="YOUR_ACCESS_KEY"
      />

      <label for="name">Name</label>
      <input type="text" name="name" id="name" required />

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

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

      <button type="submit">Send</button>
      <p id="form-status"></p>
    </form>

    <script>
      const form = document.getElementById("contact-form");
      const statusEl = document.getElementById("form-status");

      form.addEventListener("submit", async (e) => {
        e.preventDefault();
        statusEl.textContent = "Sending...";

        const data = Object.fromEntries(new FormData(form));

        try {
          const res = await fetch(
            "https://api.form-alert.com/v1/submit",
            {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify(data),
            }
          );

          if (res.ok) {
            statusEl.textContent = "Message sent!";
            form.reset();
          } else {
            statusEl.textContent =
              "Something went wrong. Try again.";
          }
        } catch {
          statusEl.textContent =
            "Something went wrong. Try again.";
        }
      });
    </script>
  </body>
</html>

Using a React/Svelte/Vue island

If you're using a UI framework integration in Astro (e.g. @astrojs/react), you can use the form component from our React guide or Svelte guide directly — just add the client:load directive.

---
import ContactForm from "../components/ContactForm";
---

<ContactForm client:load />

Next steps