Contact form
The contact form validates as people type, shows a sending state, and ends in a success or error message, all without a page reload. It needs somewhere to send the data.
Demo mode
Section titled “Demo mode”While formEndpoint in src/config/site.ts is empty, the form runs in demo mode: it validates, waits a moment and shows the success message, but sends nothing. That is how the theme demo works. Set an endpoint before you launch, or messages go nowhere.
Connect a form service
Section titled “Connect a form service”Any service that accepts a POST with FormData and answers with a 2xx status works. Formspree and Basin are two that need no server.
-
Create a form in the service and copy its endpoint URL.
-
Paste it into
site.ts:src/config/site.ts formEndpoint: 'https://formspree.io/f/your-form-id', -
Build, deploy and send yourself a test message. Most services ask you to confirm the first submission by email.
The form sends an Accept: application/json header, so services answer with JSON instead of redirecting to a thank-you page of their own. If the endpoint answers with an error or can’t be reached, the form shows an error message with your email address as a fallback.
What is sent
Section titled “What is sent”| Field | Content |
|---|---|
name |
Required |
email |
Required, checked for a valid format |
company |
Optional |
services |
Zero or more of the service chips; repeated once per choice |
budget |
One of the budget chips, or empty |
message |
Required, at least 20 characters |
language |
The page language (en, de, id), so you know how to reply |
website |
A hidden trap field for bots. Real people leave it empty |
If website has a value, the form pretends to send and quietly drops the message.
Change the options
Section titled “Change the options”The service and budget chips come from the contact section of each dictionary:
services: ['Brand', 'Website', 'Digital product', 'Packaging', 'Motion', 'Not sure yet'],budgets: ['Under £25k', '£25k to £60k', '£60k to £120k', 'Over £120k'],Each language has its own list, so budgets can be in the local currency. Error messages, labels and the success text are in the same section.
Change the rules
Section titled “Change the rules”Validation lives in src/scripts/contact-form.ts, in makeChecks. Each rule takes the field’s value and returns an error message or null. To make company required, add required to its input in contact.astro, a rule in makeChecks (and its key in the Messages type above it), and a message in the errors of each dictionary.