How do you handle async server validation without making forms feel broken?

What’s up everyone? I’m wiring up a signup form where some rules are local (required, format) but a couple are server-only (email already taken, invite code valid), and I keep tripping over weird UX like errors flickering or getting “stuck” after the user edits again.

If you’ve shipped this kind of thing, how do you structure validation state so it’s accessible (screen readers don’t spam), resilient to out-of-order responses, and still fast enough to not block typing while avoiding accidental double submits?

1 Like

Treat each server check like it’s tied to a specific snapshot of the field value, and ignore anything that comes back for an older snapshot. The easiest way is a per-field “token” (an incrementing counter) you capture when you fire the request; when the response returns, only apply it if the token still matches the latest for that field (same idea as “only the latest search wins”). For the flicker/screen reader spam part, I’ve had the best luck only announcing server errors on blur or submit. While typing, just show a quiet “Checking…” state (not an error), with aria-live="polite" on a single status region. For double submits: disable the submit button only during the actual submit request, not during background validation. Otherwise it feels like the form is randomly broken.

1 Like