I moved a client's marketing site to Astro a few weeks ago. Astro 7 was the reason — the Rust compiler and stable route caching cut the build from ~4 minutes to about 90 seconds. Fast builds were the whole point.
Then I hit the one thing Astro can't do out of the box: accept a contact form submission.
Here's the honest version of what I tried, what worked, and the two gotchas that cost me an afternoon.
Why Astro forms trip people up
Astro is component-first and ships almost zero client-side JavaScript. Most "add a form" tutorials assume a Node runtime. Three things follow from that, and they're the reason this feels different from a Next.js or Rails form:
A form has to POST somewhere. The action attribute is just a URL. There's no "submit to Astro" without an adapter.
Astro Actions need a server adapter. They're stable and genuinely type-safe, but they require output: 'server' or 'hybrid' plus @astrojs/vercel / netlify / cloudflare / node .…