PLG OS

Implementation worksheet · 7 min read

An accessible in-app survey error-state specification

Specify seven states before the survey ships: a required answer left blank, a free-text answer over the limit, a submit in flight, a submit that failed, a retry that succeeded, a survey dismissed halfway, and a survey whose host element disappears. For each one, write the text the respondent sees, where it appears, where keyboard focus goes and how assistive technology hears about it. WCAG 2.2 sets the floor: 3.3.1 Error Identification (Level A) wants the item in error identified and described in text, 3.3.3 Error Suggestion (Level AA) wants a known correction offered, and 4.1.3 Status Messages (Level AA) covers messages announced without moving focus. Passing those checks for these states is a test result for one widget. It is not a conformance claim.

An in-app survey is a small form rendered inside someone else's screen, usually in a corner, often by a third-party script. That combination produces error states nobody designed: a red outline with no words, a Submit button that does nothing when the request fails, a thank-you screen shown before the answer was stored. This specification is for whoever owns the survey widget, built in-house or configured in a tool. It covers the survey component only; the host product's own forms need their own review.

Put it into practice

1. List the states before writing any copy

Most survey specs describe the happy path and one 'required' message. Write down every state the widget can reach after the respondent acts, including the two that are easiest to forget: the failed network submit and the host element disappearing mid-answer. Each state gets a row in the worksheet below. A state without a row is a state someone improvises in production.

2. Put the error in text beside the question

3.3.1 Error Identification (Level A) asks for the item in error to be identified and the error described in text. A red border around a 0-10 scale does neither, and if color is the only signal it also runs into 1.4.1 Use of Color (Level A). Write a sentence that names the fix, such as 'Choose a score from 0 to 10 to continue', and associate it with the question group using aria-describedby so a screen reader reads it with the question.

3. Pick one focus rule per survey type

For a one-question survey, keep focus on Submit and announce the message; yanking focus around a widget the respondent opened in passing is disorienting. For a multi-question survey, move focus to the first question in error so keyboard users don't hunt for it. Write the rule down. Two surveys in the same product behaving differently is how inconsistency creeps in.

4. Treat a failed submit as an error, not a silence

The respondent pressed Submit and the request failed. The widget must keep the answer, say in text that it wasn't sent, offer a retry, and announce the message as a status message so 4.1.3 Status Messages (Level AA) is met without stealing focus. WCAG's definition of a status message explicitly includes the existence of errors. Never show 'Thanks' until the server has confirmed it stored the answer.

5. Offer the correction and keep what was typed

Where the fix is known, say it: 'Shorten your answer to 500 characters. It is 612 now.' That is 3.3.3 Error Suggestion (Level AA). Keep the typed text. Clearing a free-text answer on error forces the respondent to type it again, the pattern 3.3.7 Redundant Entry (Level A) exists to prevent within a process.

6. Handle the host disappearing

If the survey is anchored to an element that unmounts, after a route change or a panel closing, the widget should either move to a fallback position with a short status message or close and keep the partial answer according to your dismissal policy. If focus was inside the survey, move it somewhere logical instead of letting it drop to the document body. Log the event: a survey that loses its host on one route will do it to every respondent on that route.

7. Test with a keyboard and a screen reader, and write down what you heard

Run every state with the screen reader and browser pairings your users actually use, and record each announcement verbatim, with versions. 'Nothing announced' is a finding, not a pass. A clean run shows these states behave against the criteria you tested; contrast, target size, zoom and reflow still need their own checks.

Survey error-state worksheet

Copy this structure into your review document and record your observed result for each row.

Survey error-state worksheet
StateText shownFocus behaviorHow it is conveyed
Required rating left blankChoose a score from 0 to 10 to continue.Stays on Submit (one question) or moves to the scale (several)Text tied to the scale; 3.3.1, Level A
Free text over the limitShorten your answer to 500 characters. It is 612 now.Stays in the text field; typed text keptCorrection offered; 3.3.3, Level AA
Submit in flightSending your answer.Stays on Submit; repeat presses ignoredStatus message; 4.1.3, Level AA
Submit failedYour answer wasn't sent. Try again.Stays on Submit; answer keptStatus message; 4.1.3, Level AA
Retry succeededThanks, your answer was saved.Stays in the widget until the respondent closes itStatus message; 4.1.3, Level AA
Dismissed halfwayNo message shownReturns to the trigger, or a declared fallback if the survey opened itselfDismissal stored under your persistence rules
Host element removedThe survey moved to the corner of the screen.Moves with the survey if focus was inside itStatus message; 4.1.3, Level AA
Counterexample: outline onlyBorder turns red, no wordsUnchangedFails 1.4.1 and 3.3.1, both Level A

A failure worth checking

The optimistic thank-you. The widget shows 'Thanks for your feedback' the moment Submit is pressed and sends the answer in the background. When the request fails, on a flaky train connection or behind one customer's strict content security policy, the respondent has been told the answer was saved and it wasn't. Nothing is announced because nothing was ever shown, and the response dashboard just looks a little low. Gate the thank-you on the server's confirmation and give the failure its own text, its own announcement and its own row in the worksheet.

Common questions

Should survey errors use role=alert?

Sparingly. The WAI-ARIA Authoring Practices alert pattern describes an alert as a brief, important message that doesn't move focus, and warns that frequent interruptions hurt usability. A polite status region is usually enough for 'answer not sent'. Save role=alert for the rare message a respondent must hear immediately.

If these checks pass, is the survey WCAG 2.2 conformant?

No. WCAG conformance applies to full web pages and complete processes, and it can't be achieved by excluding part of a page, so the host product matters as much as the widget. These checks cover one component's error states against a handful of criteria. Treat them as evidence for a wider review, not as a badge.

Basis and scope

This is a proposed implementation method using illustrative examples, not a measured benchmark or a customer case study. Prepared with AI assistance. Validate product-specific behavior against current documentation and your own test environment.

Continue with PLG OS

Explore onboarding →