Astro

Astro and Formcrest are a natural fit: your site stays fully static, and the form posts straight to our endpoint.

The zero-JavaScript way

Because the form posts directly to Formcrest, a static .astro page needs no server endpoint, no adapter, and no client JavaScript. Drop this into any page or component — the hidden _honey field is our spam honeypot:

---
// src/pages/contact.astro — fully static, no client JS
---

<form action="https://api.formcrest.com/v1/submit/abc123" method="POST">
  <input type="email" name="email" required />
  <textarea name="message" required></textarea>
  <input
    type="text"
    name="_honey"
    style="display:none"
    tabindex="-1"
    autocomplete="off"
  />
  <button type="submit">Send</button>
</form>

On success the visitor is redirected to your form's success URL (set it in the form's settings, or send a hidden redirect field) — our default thank-you page is used otherwise.

In-page success state with a script

Want to stay on the page? Add a plain <script> — no framework island needed:

<form id="contact" action="https://api.formcrest.com/v1/submit/abc123" method="POST">
  <!-- …fields as above… -->
</form>
<p id="contact-done" hidden>Thanks — we'll be in touch.</p>

<script>
  const form = document.querySelector("#contact");
  form?.addEventListener("submit", async (event) => {
    event.preventDefault();
    const response = await fetch(form.action, {
      method: "POST",
      headers: { Accept: "application/json" },
      body: new FormData(form),
    }).catch(() => null);

    if (response?.ok) {
      form.hidden = true;
      document.querySelector("#contact-done").hidden = false;
    } else {
      form.submit(); // fall back to the full-page flow
    }
  });
</script>

This is progressive enhancement: with JavaScript disabled (or if the fetch fails), the form still posts normally and follows the redirect.

Framework islands

If your form lives inside a React island, use the useFormSubmit hook from @formcrest/sdk/react exactly as in the React & Next.js guide — just remember the client:load directive on the island. Vue and Svelte islands can use the framework-agnostic submit() function the same way as in the Vue and Svelte guides.

Next steps