Handbook
Tools & Patterns

React Accessibility Tools and Patterns

Last updated by Noel Varanda (opens in a new tab),
Accessibility
React
A11y
eslint-plugin-jsx-a11y
axe-core
react-helmet
as prop
fragments
Semantic markup

This guide aims to provide you with the necessary knowledge and techniques to make your React applications accessible. Be sure to understand the fundamentals of a11y before implementing these tools. By following these, you can create inclusive and user-friendly React applications that cater to a wider audience.

Tools

eslint-plugin-jsx-a11y

Leverage the eslint-plugin-jsx-a11y plugin to catch accessibility issues during development. Find more information in the documentation (opens in a new tab).

  1. Install the appropriate ESLint plugin (opens in a new tab) for your code editor.
  2. Add/update your .eslintrc.json file:
{
  "extends": ["react-app", "plugin:jsx-a11y/recommended"]
}

If you would like an even stricter subset of rules, switch to strict mode:

{
  "extends": ["react-app", "plugin:jsx-a11y/strict"]
}

Refer to the eslint-plugin-jsx-a11y supported rules section (opens in a new tab) to understand the difference between recommended and strict mode.

@axe-core/react

reportA11y.tsx
export const reportAccessibility = async (
  App: typeof React,
  config?: Record<string, unknown>
): Promise<void> => {
  if (typeof window === 'undefined' || process.env.NODE_ENV === 'production') {
    return;
  }
 
  const axe = await import('@axe-core/react');
  const ReactDOM = await import('react-dom');
 
  axe.default(App, ReactDOM, 1000, config);
};

React Helmet

Ensure proper page titles using react-helmet (opens in a new tab).

Use the Head component for Next.js (opens in a new tab).

import React from 'react';
import { Helmet } from 'react-helmet';
 
const MyComponent: React.FC = () => (
  <>
    <Helmet>
      <title>My Page Title</title>
      <meta name="description" content="This is the description of my page" />
    </Helmet>
    {/* Your component's JSX */}
  </>
);

Patterns

"as" prop pattern

Consider using the "as" prop pattern when abstracting components to ensure proper semantic structure, including icons, labels, alt text, button text, and more.

type ButtonProps = {
  as?: keyof JSX.IntrinsicElements | React.ComponentType<any>;
  children: ReactNode;
  onClick?: () => void;
};
 
const Button: React.FC<ButtonProps> = ({
  as = 'button',
  children,
  onClick,
}) => {
  const Component = as;
  return <Component onClick={onClick}>{children}</Component>;
};

Usage:

<Button as="a" href="/home">
  Go Home
</Button>
 
// outputs <a href="/home">Go Home</a>

In this example, the Button component accepts an "as" prop that allows users to customize the rendered element type. By specifying the "as" prop as "a" and providing the "href" attribute, the Button component is rendered as an anchor element (<a>) with the text "Go Home" and a link to "/home".

Fragments

Use fragments to avoid unnecessary HTML markup and maintain accessibility standards.

const MyComponent = () => (
  <>
    <h1>Main Heading</h1>
    <p>Some content here.</p>
  </>
);

We recommend reading this article (opens in a new tab) to further understand what Semantic Markup is and how to use it.


Keep up to date with any latest changes or announcements by subscribing to the newsletter below.