Skip to main content

Command Palette

Search for a command to run...

12 Resources for Designing Better Error Messages and Empty States

Research, tools, libraries, and reference material for designing error messages and empty states that actually help users

Published

Error messages and empty states are where products either earn trust or lose it. The resources below cover the full range: usability research, accessibility requirements, design patterns, developer tools, and validation libraries. Each one is worth bookmarking.

1. Nielsen Norman Group

Nielsen Norman Group has produced more usability research on error messages than any other organization. Their studies consistently show that unclear error messages correlate directly with task abandonment. The research is paywalled for some reports, but a significant volume of their writing on error UX, form design, and empty states is available free on their website.

Start with their work on error prevention and recovery, which distinguishes between errors caused by users (validation failures) and errors caused by the system (timeouts, server errors), and prescribes different message patterns for each.

2. W3C Web Accessibility Initiative

The Web Accessibility Initiative at W3C publishes the authoritative accessibility guidelines that govern how error messages must be communicated to assistive technology users. The WAI site hosts WCAG documentation, technique libraries, and tutorials on specific patterns including form validation and error identification.

Error-related criteria in WCAG 2.1 (3.3.1, 3.3.3, 4.1.3) are explained with examples in the WAI techniques documents. This is the primary reference for teams building to accessibility compliance requirements.

3. WebAIM

WebAIM translates W3C accessibility guidelines into practical developer guidance. Their articles on form validation and ARIA usage are among the most practical implementations of WCAG error requirements available.

WebAIM also provides the Wave browser extension for visual accessibility checking, which flags error-related ARIA problems (missing labels, disconnected error messages, and aria-invalid misuse) directly in the browser.

4. The A11Y Project

The A11Y Project maintains a community-sourced checklist of WCAG requirements, organized by category. The checklist items for forms and error messages are specific and actionable, making them useful both for developers implementing error messages and for QA checking finished implementations.

The project's blog and resource index link to articles on specific ARIA patterns, tested across real screen reader combinations. The checklist format makes it easy to use as a literal testing rubric before shipping.

5. MDN Web Docs

MDN Web Docs is the most comprehensive reference for the web platform attributes used in accessible error messages: aria-invalid, aria-describedby, aria-live, aria-atomic, role="alert", and the HTML constraint validation API.

The constraint validation API (input.validity, input.validationMessage, input.setCustomValidity()) is particularly useful for error message customization in native HTML forms. MDN's coverage of it is complete and includes browser compatibility data.

6. axe-core

axe-core from Deque Systems is the most widely used open-source accessibility testing engine. It can be run in the browser console, integrated into Playwright or Cypress tests, or added to a CI pipeline.

Integrating it into your test suite takes about five minutes:

// Using @axe-core/playwright
import { checkA11y } from 'axe-playwright';

test('form error states are accessible', async ({ page }) => {
  await page.goto('/signup');
  await page.click('[type="submit"]'); // trigger validation errors
  await checkA11y(page, null, {
    runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa', 'wcag21aa'] }
  });
});

axe-core catches structural problems: missing aria-describedby connections, aria-invalid set without a corresponding error message, and color-contrast failures in error states. It does not catch announcement timing issues, which require manual screen reader testing.

whiteboard user interface flow sketches planning Photo by Walls.io on Pexels

7. Deque Systems

Deque develops axe-core and publishes substantial research on accessible UI patterns, including error message announcement behavior across different screen reader and browser combinations. Their documentation on live region timing is especially useful.

Deque's enterprise tools (axe DevTools, axe Monitor) are used by large teams for continuous accessibility monitoring. Their free documentation, however, covers the same underlying patterns with enough depth for most teams.

8. Inclusive Components

Inclusive Components by Heydon Pickering is a reference on building accessible UI components. The site includes detailed analyses of notifications, toggles, and form patterns, with screen reader output documented for each implementation variant.

Each article shows the accessible version, explains why each attribute is used, and documents what a screen reader actually announces at each interaction step. This level of detail is hard to find elsewhere.

9. React Hook Form

React Hook Form handles the ergonomics of form validation in React applications, including error state management. Its formState.errors object provides per-field error data that maps cleanly to aria-invalid and aria-describedby connections.

A basic error message integration looks like this:

import { useForm } from 'react-hook-form';

function SignupForm() {
  const { register, handleSubmit, formState: { errors } } = useForm();

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="email">Email</label>
      <input
        id="email"
        type="email"
        aria-invalid={errors.email ? 'true' : 'false'}
        aria-describedby={errors.email ? 'email-error' : undefined}
        {...register('email', {
          required: 'Email is required',
          pattern: { value: /\S+@\S+\.\S+/, message: 'Enter a valid email address' }
        })}
      />
      {errors.email && (
        <span id="email-error" role="alert">
          {errors.email.message}
        </span>
      )}
    </form>
  );
}

The library handles focus management and re-validation automatically. You wire in the ARIA attributes and it handles the form state.

10. Zod

Zod is a TypeScript-first schema validation library that generates typed error messages from schema definitions. It integrates directly with React Hook Form and other form libraries, and is increasingly used for both client-side form validation and server-side API validation.

The advantage for error messages: Zod validation errors are structured, type-safe, and composable. You define the schema and the messages once; the library surfaces them consistently across form and API validation contexts. Custom error messages are set at the schema level, making them easy to keep consistent.

11. Storybook

Storybook is a component development tool that lets you render components in isolation with specific props and states. For error messages, this means you can write stories that show the default state, the error state, and the recovery state of every form component without building out a full form flow to test them.

Teams that use Storybook for component development typically catch error message problems earlier than teams that only see error states in integration tests or production. When the error state is a first-class story alongside the default state, it gets the same design and code review attention.

12. Smashing Magazine

Smashing Magazine has published extensively on form UX, error message design, and empty states from both design and development perspectives. The archive is searchable and deep.

Articles on error UX often cover the language and framing of error messages (not just the technical implementation), which is an underrepresented topic in developer-focused resources. The "blame avoidance" principle for error message language (writing "Check that all fields are complete" rather than "You left fields empty") is covered well in their UX writing archive.


"The tooling around accessible error messages has gotten genuinely good. Between axe-core in your CI and a few hours of manual screen reader testing, you can get most of the way to accessible error states with a small and well-defined body of work." - Dennis Traina, founder of 137Foundry


For a structured framework covering how to design both the content of error messages and the interaction patterns around them, 137Foundry's design resources include a detailed guide in the article How to Design Error Messages and Empty States That Actually Help Users, which covers pattern selection for different error types and how to treat empty states as positive experiences rather than edge cases.

CSS for error states is worth treating as carefully as the content:

.field-error input,
.field-error select,
.field-error textarea {
  border-color: #c0392b;
  /* Always pair color with a non-color indicator */
  outline: 2px solid #c0392b;
  outline-offset: 2px;
}

.error-message {
  color: #c0392b;
  font-size: 0.875rem;
  margin-top: 0.25rem;
  /* Add an icon so error state isn't color-only */
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.error-message::before {
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
  background-image: url("data:image/svg+xml,..."); /* error icon */
  background-size: contain;
}

WCAG 1.4.1 requires that color is not used as the only visual means of conveying information -- meaning error states must use border width, icon, or label in addition to red coloring. The CSS pattern above adds an outline and an icon alongside the color change to meet this requirement.

The combination of research (NNGroup, WebAIM), implementation guidance (MDN, Inclusive Components), developer tooling (axe-core, React Hook Form, Zod), and component infrastructure (Storybook) covers the full error-message design and development workflow. Most of these resources are free.