Back to blog

Travel

Field notes from a week on the coast

Early light, long walks, and the frames that made the final edit after everything else was cut.

Soft morning light over the sea

Most contact forms are slow for boring reasons: a heavy script, an extra redirect, and an error message nobody designed. This guide fixes all three in about an afternoon.

Why speed matters#

People decide whether a form worked in the first second after they press submit. A clear, quick response keeps them on the page and makes the follow-up feel personal.

Set up the endpoint#

Point the form at your endpoint and send the fields with fetch. Keep the request small and always return JSON so the page can show the right message. The MDN guide to fetch covers the details.

TypeScript
type Result = { ok: true } | { ok: false; message: string }

export async function submitForm(form: HTMLFormElement): Promise<Result> {
    const response = await fetch(form.action, {
        method: 'POST',
        headers: { Accept: 'application/json' },
        body: new FormData(form),
    })
    if (response.ok) return { ok: true }
    const body = await response.json().catch(() => ({}))
    return { ok: false, message: body.message ?? 'Something went wrong. Please try again.' }
}

Test it from the terminal#

Before touching the page, confirm the endpoint answers with a quick request:

Bash
curl -X POST https://example.com/f/contact \
  -H "Accept: application/json" \
  -F "email=hello@example.com" \
  -F "message=Testing <angle brackets> & ampersands"

Handle every state#

  • Disable the button while the request is in flight.

  • Show the server message when validation fails.

  • Keep what people typed if anything goes wrong.

What changed#

After the changes, the same form felt noticeably quicker on a mid-range phone:

Measure

Before

After

Time to response

1.8 s

0.4 s

Completed forms

61%

78%

Script size

84 KB

3 KB

The final setup: one endpoint, one script, and a follow-up reminder for every enquiry.

The fastest form is the one that answers before people start to wonder.

Next steps#

  1. Add a follow-up reminder for every new enquiry.

  2. Write a short confirmation email in your own voice.

  3. Review the slowest pages once a month.


That is the whole recipe. Small, quick, and kind to the people filling it in.

Continue the conversation

This note sits under every article. Replace it, or remove it from the article layout.