Skip to main content
The Next.js team is committed to making Next.js accessible to all developers and their users. Built-in accessibility features are enabled by default, so you don’t need to configure them.

Route announcements

When navigating between pages in a traditional multi-page application, screen readers announce the page title on load so users know the page has changed. Next.js also supports client-side transitions via next/link for better performance. To ensure assistive technology is notified of these transitions, Next.js includes a route announcer by default — no configuration required. The route announcer determines what to announce by checking, in order:
  1. document.title
  2. The first <h1> element on the page
  3. The URL pathname
Give each page a unique, descriptive <title> to ensure screen readers announce meaningful page names on navigation.
import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'About us — Acme',
}

export default function AboutPage() {
  return <h1>About us</h1>
}

Focus management

During client-side navigation, Next.js manages focus to keep keyboard users oriented. After a route transition:
  • Focus moves to the top of the new page’s content, not the browser chrome.
  • Users navigating with a keyboard or screen reader can begin reading or tabbing through the new content immediately.
For custom focus handling, you can use the useRouter hook to listen for navigation events and manually call .focus() on the relevant element.

ESLint integration

Next.js ships with an integrated ESLint setup that includes eslint-plugin-jsx-a11y. This plugin catches common accessibility mistakes at write time, warning on:
RuleWhat it checks
aria-propsValid ARIA attribute names
aria-proptypesCorrect value types for ARIA attributes
aria-unsupported-elementsARIA roles on elements that don’t support them
role-has-required-aria-propsRequired ARIA properties for a given role
role-supports-aria-propsARIA attributes allowed by the element’s role
alt-textalt attribute on <img>, <area>, and <input type="image">
anchor-has-contentNon-empty link text
interactive-supports-focusFocusability of interactive elements
Run the linter with:
next lint
For more details on configuring ESLint in Next.js, see the ESLint configuration reference.

Best practices

Use HTML elements for their intended purpose. A <button> handles keyboard events automatically; a <div onClick> does not.
// Prefer
<button onClick={handleSubmit}>Submit</button>

// Avoid
<div role="button" onClick={handleSubmit}>Submit</div>
Ensure sufficient contrast between foreground text and background colors. WCAG 2.2 requires a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text.Use tools like the WebAIM Contrast Checker or browser DevTools accessibility panels to audit your palette.
All interactive elements must be reachable and operable via keyboard. Test your application by navigating entirely with Tab, Shift+Tab, Enter, and arrow keys.
Respect the user’s motion preference with the prefers-reduced-motion media query:
@media (prefers-reduced-motion: reduce) {
  .animated {
    animation: none;
    transition: none;
  }
}
Every form input must have an associated <label>. Use htmlFor with a matching id, or wrap the input inside the label.
<label htmlFor="email">Email address</label>
<input id="email" type="email" />

External resources

Build docs developers (and LLMs) love