Skip to content
StellarBoat

Form Components

Production-ready form components with progressive enhancement, spam protection, and accessibility built in. Submissions on this demo are real — they're written to a Google Sheet via a gated Worker endpoint.

Features

✓ Progressive Enhancement

All forms work with native HTML POST without JavaScript (though spam verification requires it — see below). When JS is available, they upgrade to JSON submission with inline status feedback.

✓ Spam Protection

A honeypot field, Worker-side rate limiting, and Cloudflare Turnstile all run before a submission is forwarded anywhere.

✓ Accessibility

All inputs have labels, error messages announce via ARIA, submit button shows aria-busy during submission.

✓ No External Dependencies

Pure Astro components with vanilla TypeScript. No React, Vue, or form libraries.


Configuration

Global Default (src/config/forms.ts)

import type { FormsConfig } from '../types/config';

export const forms: FormsConfig = {
  endpoint: '/api/forms',
  turnstileSiteKey: import.meta.env.PUBLIC_TURNSTILE_SITE_KEY,
};

Per-Component Override

<!-- Route one form instance to a different Worker deployment -->
<ContactForm endpoint="https://staging.example.com/api/forms" />

<!-- Prefix field ids to avoid collisions if you render two of the
     same form type on one page -->
<ContactForm idPrefix="footer-contact" />

Contact Form

Live Example

Uses the default endpoint from your forms config.

Override the Endpoint

Route a single instance to a different Worker deployment:

<ContactForm
  endpoint="https://staging.example.com/api/forms"
/>

Lead Capture Form

Lead Capture Form

Four-field form for lead generation: name, email, company (optional), phone (optional). Submits to the global default endpoint.


Newsletter Form

Vertical Layout (Default)

Single-field email form in vertical layout. Good for dedicated newsletter signup pages.

Compact Horizontal Layout

<NewsletterForm compact />

Override the Endpoint

<NewsletterForm
  endpoint="https://staging.example.com/api/forms"
/>