Onboarding UI is accessible to users with disabilities
Why it matters
Inaccessible signup and onboarding flows violate WCAG 2.2 SC 1.3.1 (Info and Relationships), 2.1.1 (Keyboard), 2.4.3 (Focus Order), 2.4.11 (Focus Not Obscured), and Section 508 §502.3 — and expose the company to ADA Title III litigation risk in the US. Form fields without labels are unusable with a screen reader; missing role="alert" means error messages are invisible to assistive technology. These aren't cosmetic gaps: they legally and functionally exclude users with disabilities from your product at the first interaction.
Severity rationale
Critical because inaccessible onboarding is both a legal exposure under ADA/Section 508 and a hard blocker for users who rely on screen readers or keyboard navigation to complete signup.
Remediation
In src/app/(auth)/signup/page.tsx, associate every input with a visible label and link errors via aria-describedby:
<div>
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
aria-describedby={emailError ? "email-error" : undefined}
/>
{emailError && (
<p id="email-error" role="alert" className="text-destructive text-sm">
{emailError}
</p>
)}
</div>
Audit every outline: none in your global CSS — either remove it or add a visible :focus-visible replacement. For modal dialogs, use a focus trap library (focus-trap-react) so keyboard users can't tab outside the dialog.
Detection
-
ID:
accessibility-of-onboarding -
Severity:
critical -
What to look for: Count all form fields in signup and onboarding. For each, classify whether it has an associated
<label>oraria-label. Count error messages and check foraria-describedbyorrole="alert". Enumerate interactive elements and verify keyboard navigability. Check focus management in modals. Countoutline: noneusages. -
Pass criteria: 100% of form fields in signup have an associated
<label>oraria-label. Error messages usearia-describedbyorrole="alert". All interactive elements are reachable via keyboard. Nooutline: nonewithout a visible focus replacement. Report even on pass: "Checked N form fields — all have labels. N error states use role=alert." -
Fail criteria: Any of: form fields without labels or
aria-label; error messages that only appear visually with norole="alert"; interactive elements not reachable by keyboard; focus not trapped in modal dialogs; focus indicators removed withoutline: noneand no visible replacement. -
Skip (N/A) when: The project has no user-facing UI (API-only, CLI tool, or library).
-
Detail on fail: List specific failures. Example:
"Signup form: email and password fields have no associated <label>. Error messages have no role='alert'. Modal dialog does not trap focus. Tab order skips the 'Show password' toggle." -
Remediation: In your signup form at
src/app/(auth)/signup/page.tsx:<div> <Label htmlFor="email">Email</Label> <Input id="email" type="email" aria-describedby={error ? "email-error" : undefined} /> {error && <p id="email-error" role="alert" className="text-destructive text-sm">{error}</p>} </div> -
Cross-reference: For a comprehensive accessibility review across the full application, the Accessibility Fundamentals Audit covers WCAG 2.1 AA compliance in depth.
External references
- wcag:2.2 · 1.3.1 — Info and Relationships
- wcag:2.2 · 2.1.1 — Keyboard
- wcag:2.2 · 2.4.3 — Focus Order
- wcag:2.2 · 2.4.11 — Focus Not Obscured (Minimum)
- section-508:2018-refresh · 502.3 — Accessibility Services
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-onboarding·automated