|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Accessibility auditing with react-axe and eslint-plugin-jsx-a11y |
| 4 | +hero: hero-accessibility-auditing-react.jpg |
| 5 | +subhead: | |
| 6 | + Your React site is not progressive if it's not accessible. Auditing during development can help you spot any issues! |
| 7 | +date: 2019-04-29 |
| 8 | +description: | |
| 9 | + react-axe is a library that audits a React application and logs any |
| 10 | + accessibility issues to the Chrome DevTools console. eslint-plugin-jsx-a11y |
| 11 | + is an ESLint plugin that identifies and enforces a number of accessibility |
| 12 | + rules directly in your JSX. Using them in combination can provide a |
| 13 | + comprehensive auditing approach to find and fix any accessibility concerns in |
| 14 | + your application. |
| 15 | +author: houssein |
| 16 | +--- |
| 17 | + |
| 18 | +{% Aside %} |
| 19 | + If you would like to learn about the basic concepts behind accessibility in |
| 20 | + web pages, refer to the [What is accessibility](/what-is-accessibility) guide |
| 21 | + first. |
| 22 | +{% endAside %} |
| 23 | + |
| 24 | +[`react-axe`](https://github.com/dequelabs/react-axe) is a library that audits a |
| 25 | +React application and logs any accessibility issues to the Chrome DevTools |
| 26 | +console. It uses the open-source [axe](https://github.com/dequelabs/axe-core) |
| 27 | +testing library to flag any issues and their severity. |
| 28 | + |
| 29 | +[`eslint-plugin-jsx-a11y`](https://github.com/evcohen/eslint-plugin-jsx-a11y) is |
| 30 | +an ESLint plugin that identifies and enforces a number of accessibility rules |
| 31 | +directly in your JSX. Using this in combination with a tool that tests the final |
| 32 | +rendered DOM, such as `react-axe`, can provide a comprehensive auditing approach |
| 33 | +to find and fix any accessibility concerns. |
| 34 | + |
| 35 | +## Why is this useful? |
| 36 | + |
| 37 | +It is crucial to build web sites that provide every user, regardless of any |
| 38 | +impairment or restriction, the capability to access its content. Using auditing |
| 39 | +libraries such as `react-axe` and `eslint-plugin-jsx-a11y` during the |
| 40 | +development of your React application will automatically surface any |
| 41 | +accessibility issues as they pop up. |
| 42 | + |
| 43 | +## Use eslint-plugin-jsx-a11y |
| 44 | + |
| 45 | +React already supports writing accessible HTML elements within JSX syntax. For |
| 46 | +example, you only need to use the `htmlFor` attribute instead of `for` to link a |
| 47 | +label to a specific form element within a React component. |
| 48 | + |
| 49 | +```html |
| 50 | +<input id="promo" type="checkbox"> |
| 51 | +<label htmlFor="promo">Receive promotional offers?</label> |
| 52 | +``` |
| 53 | + |
| 54 | +The |
| 55 | +[React accessibility documentation](https://reactjs.org/docs/accessibility.html) |
| 56 | +covers all the nuances of handling accessibility concerns within a React |
| 57 | +component. To make it easier to spot these issues during development, Create |
| 58 | +React App (CRA) includes the **`eslint-plugin-jsx-a11y`** plugin for ESLint by |
| 59 | +default. |
| 60 | + |
| 61 | +To enable pre-configured linting provided by CRA: |
| 62 | + |
| 63 | +1. Install the appropriate ESLint plugin for your code editor |
| 64 | +2. Add a `.eslintrc.json` file to your project |
| 65 | + |
| 66 | +```json |
| 67 | +{ |
| 68 | + "extends": "react-app" |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +{% Aside %} |
| 73 | + You can find more details about configuring your editor to support out-of-box |
| 74 | + linting in the |
| 75 | + [CRA documentation](https://facebook.github.io/create-react-app/docs/setting-up-your-editor). |
| 76 | +{% endAside %} |
| 77 | + |
| 78 | +Some common accessibility issues will now show up. |
| 79 | + |
| 80 | + |
| 81 | + |
| 82 | +To check for even more accessibility rules, modify the file to automatically |
| 83 | +include all the recommended rules by the plugin: |
| 84 | + |
| 85 | +```json |
| 86 | +{ |
| 87 | + "extends": ["react-app", "plugin:jsx-a11y/recommended"] |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +An even stricter subset of rules is also supported: |
| 92 | + |
| 93 | +```json |
| 94 | +{ |
| 95 | + "extends": ["react-app", "plugin:jsx-a11y/strict"] |
| 96 | +} |
| 97 | +``` |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +The project |
| 102 | +[documentation](https://github.com/evcohen/eslint-plugin-jsx-a11y#difference-between-recommended-and-strict-mode) |
| 103 | +provides information on the differences between recommended and strict mode. |
| 104 | + |
| 105 | +## Use react-axe |
| 106 | + |
| 107 | +`eslint-plugin-jsx-a11y` can help you easily pinpoint any accessibility issues |
| 108 | +in your JSX, but it does not test any of the final HTML output. **`react-axe`** |
| 109 | +is a library that does exactly this by providing a React wrapper around the |
| 110 | +[`axe-core`](https://github.com/dequelabs/axe-core) testing tool by Deque Labs. |
| 111 | + |
| 112 | +Install the library as a development dependency to begin: |
| 113 | + |
| 114 | +``` |
| 115 | +npm install --save-dev react-axe |
| 116 | +``` |
| 117 | + |
| 118 | +You now only need to initialize the module in `index.js`: |
| 119 | + |
| 120 | +```js |
| 121 | +if (process.env.NODE_ENV !== 'production') { |
| 122 | + import('react-axe').then(axe => { |
| 123 | + axe(React, ReactDOM, 1000); |
| 124 | + ReactDOM.render(<App />, document.getElementById('root')); |
| 125 | + }); |
| 126 | +} else { |
| 127 | + ReactDOM.render(<App />, document.getElementById('root')); |
| 128 | +} |
| 129 | +``` |
| 130 | + |
| 131 | +A |
| 132 | +[dynamic import](https://developers.google.com/web/updates/2017/11/dynamic-import) |
| 133 | +is used here to only load the library when it is not in production mode before |
| 134 | +rendering and booting up the root `App` component. This ensures that it is not |
| 135 | +unecessarily included in the final production bundle. |
| 136 | + |
| 137 | +Now when you run the application during development, issues are surfaced |
| 138 | +directly to the Chrome DevTools console. |
| 139 | + |
| 140 | +<img class="w-screenshot w-screenshot--filled" src="./react-axe-devtools.png" alt="React Axe in Chrome DevTools"> |
| 141 | + |
| 142 | +A severity level is also assigned for each violation. These levels are: |
| 143 | + |
| 144 | +* Minor |
| 145 | +* Moderate |
| 146 | +* Serious |
| 147 | +* Critical |
| 148 | + |
| 149 | +{% Aside %} |
| 150 | + If you would like to include accessibility testing in your unit testing |
| 151 | + workflow, take a look at the |
| 152 | + [Jest and axe integration example](https://github.com/dequelabs/axe-core/tree/develop/doc/examples/jest_react) |
| 153 | + to understand how. |
| 154 | +{% endAside %} |
| 155 | + |
| 156 | +## Conclusion |
| 157 | + |
| 158 | +1. If you are building a site with React, include accessibility auditing into |
| 159 | + your workflow early to catch problems as you build your components. |
| 160 | +2. Use `eslint-plugin-jsx-a11y` to add accessibility checks into your linting |
| 161 | + workflow. CRA already comes with it included, but switch to either the |
| 162 | + recommended or strict mode. |
| 163 | +3. In addition to local development testing, include `react-axe` into your |
| 164 | + application to catch any issues on the final rendered DOM. Do not include it |
| 165 | + into your production bundle. |
0 commit comments