CatchForm

Contact Form for Astro

Build a contact form component for your Astro site that sends submissions directly to your email without any backend server.

Overview

This guide shows how to create a reusable contact form component in Astro that works without a backend. The form sends submissions directly to CatchForm, which delivers them to your inbox.

Prerequisites

  • An Astro project (v3.0 or later)
  • A CatchForm account with an active form

Step 1: Set Up CatchForm

Sign up for CatchForm and create a new form. You'll receive a unique token. Store it in your .env file:

PUBLIC_CATCHFORM_TOKEN=your-token-here

The PUBLIC_ prefix makes it safe to expose in the browser (the token is already public since the form accepts submissions from any origin).

Step 2: Create the ContactForm Component

Create a new file src/components/ContactForm.astro:

---
const token = import.meta.env.PUBLIC_CATCHFORM_TOKEN;
---

<form
  action={`https://catchform.dev/f/${token}`}
  method="POST"
  class="contact-form"
>
  <input
    type="hidden"
    name="_gotcha"
    value=""
  >

  <div class="form-group">
    <label for="name">Name</label>
    <input
      id="name"
      type="text"
      name="name"
      required
    >
  </div>

  <div class="form-group">
    <label for="email">Email</label>
    <input
      id="email"
      type="email"
      name="email"
      required
    >
  </div>

  <div class="form-group">
    <label for="message">Message</label>
    <textarea
      id="message"
      name="message"
      rows="5"
      required
    ></textarea>
  </div>

  <button type="submit">Send Message</button>
</form>

<style>
  .contact-form {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: 500px;
  }

  .form-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  label {
    font-weight: 500;
    font-size: 0.95rem;
  }

  input,
  textarea {
    padding: 0.625rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-family: inherit;
    font-size: 1rem;
  }

  input:focus,
  textarea:focus {
    outline: none;
    border-color: #4f46e5;
    box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.1);
  }

  button {
    padding: 0.75rem 1.5rem;
    background-color: #4f46e5;
    color: white;
    border: none;
    border-radius: 4px;
    font-weight: 600;
    cursor: pointer;
    font-size: 1rem;
  }

  button:hover {
    background-color: #4338ca;
  }

  button:active {
    transform: scale(0.98);
  }
</style>

Step 3: Use the Component

Import and use the component in any Astro page or layout:

---
import ContactForm from '../components/ContactForm.astro';
---

<html lang="en">
  <head>
    <title>Contact Us</title>
  </head>
  <body>
    <main>
      <h1>Get in Touch</h1>
      <ContactForm />
    </main>
  </body>
</html>

Customization

Add a Success Message

After form submission, redirect the user to a success page. In your CatchForm dashboard, configure the redirect URL (e.g., /thank-you), then create a corresponding Astro page.

Add More Fields

Simply add more form groups to the component. Change the name attribute to customize how the field appears in your email:

<div class="form-group">
  <label for="company">Company</label>
  <input
    id="company"
    type="text"
    name="company"
  >
</div>

Style with Your Design System

The component uses local scoped styles. Replace them with your own CSS utilities (Tailwind, Pico, etc.) or external stylesheets.

Pro Tips

File Attachments

Pro plan users can accept file uploads. Add an input with type="file" and ensure the form has enctype="multipart/form-data". Allowed types: JPEG, PNG, GIF, PDF. Maximum size: 5 MB.

Client-Side Validation

The form uses HTML5 validation attributes (required, type="email"). Browsers enforce these, but always validate on the server side (CatchForm does).

Spam Protection

The honeypot field is already included in the component. Bots will fill it and their submissions will be rejected automatically.

Next Steps

Your form is now live. Check your inbox for submissions. Need more help?