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?