Skip to content

Pages need a title

  • Rule: axe/document-title
  • Checks: Documents must have <title> element to aid in navigation
  • WCAG: 2.4.2
  • Fix class: content: A fix needs authored text.
  • People who use a screen reader or a braille display, most of them blind.
  • People with cognitive, learning or attention disabilities.
  • People with low vision, who zoom, magnify or need strong contrast.

Add a <title> that says what the page is for, most specific part first, then the site’s name. Build it from the page’s main heading and the site name the other pages use; never invent a topic the page does not state.

<head>
<meta charset="utf-8">
<title>Order history - Acme</title>
</head>

A script sets the title after the page loads, or a single-page app leaves it empty

Section titled “A script sets the title after the page loads, or a single-page app leaves it empty”

Put a real <title> in the HTML the server sends. On each client-side route change, set document.title to name the new view.

Giving every page the same title, such as the site’s name alone

Section titled “Giving every page the same title, such as the site’s name alone”

axe accepts it, but people cannot tell pages, tabs or history entries apart, and screen reader users hear the same words on every page. A title must describe the page’s topic or purpose.

Setting only a <meta> title, such as og:title

Section titled “Setting only a <meta> title, such as og:title”

Link previews read it, but browsers and assistive technology do not, and axe still reports the page.

The part of the fix that differs in React, in its syntax. The rest of the guidance holds.

Render a <title> in the route’s component: React 19 moves it into <head> and removes it when the component unmounts. React adds it beside a <title> already in index.html instead of replacing it, so remove that one, or keep it and set document.title from an effect instead.

function OrdersPage({ siteName }) {
return (
<main>
<title>{`Orders - ${siteName}`}</title>
<h1>Orders</h1>
</main>
);
}

A <title> mixes text and a value, such as <title>Orders - {siteName}</title>

Section titled “A <title> mixes text and a value, such as <title>Orders - {siteName}</title>”

Pass one string, built with a template literal. Several children can leave the title empty, often without an error in the browser.

Rendering a <title> in both a layout and a page

Section titled “Rendering a <title> in both a layout and a page”

React keeps both in <head>, and the browser shows whichever comes first there, which follows render order rather than which title belongs to the page. Render one <title> per page.

axe-core’s documentation of the rule

CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.