Astro

Astro's static-first approach makes it a perfect fit for FormFast. Use a plain HTML form or add a client-side script for AJAX.

Static HTML form

This works with zero JavaScript and is included in Astro's static build:

src/pages/contact.astro
---
// No JavaScript needed
---

<html>
  <body>
    <h1>Contact Us</h1>
    <form action="https://formfa.st/f/your_endpoint_id" 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"></textarea>
      </label>

      <input type="hidden" name="_gotcha" style="display:none" />
      <input type="hidden" name="_next" value="https://yoursite.com/thanks" />

      <button type="submit">Send</button>
    </form>
  </body>
</html>
Since Astro pages are static, add a _next redirect so users come back to your site after submitting.

With client-side JavaScript

For an AJAX experience without a full page redirect, add a <script> tag:

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

<form id="contact-form">
  <input type="text" name="name" placeholder="Name" required />
  <input type="email" name="email" placeholder="Email" required />
  <textarea name="message" placeholder="Message"></textarea>
  <input type="hidden" name="_gotcha" style="display:none" />
  <button type="submit">Send</button>
  <p id="status"></p>
</form>

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

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

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

    const res = await fetch("https://formfa.st/f/your_endpoint_id", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
      body: JSON.stringify(data),
    });

    if (res.ok) {
      status.textContent = "Thanks! We'll be in touch.";
      form.reset();
    } else {
      status.textContent = "Something went wrong.";
    }
  });
</script>

React island

If you're using Astro with React islands, you can use the same React component from our React guide. Just add the client:load directive:

Astro
---
import { ContactForm } from "../components/ContactForm";
---

<ContactForm client:load />