# Every page has a unique, descriptive title

- **Pattern:** `ab-000105` (`accessibility-wcag.operable.page-title`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000105
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000105)

## Why it matters

Generic or missing page titles mean screen reader users hear "untitled" or the app name alone when switching browser tabs or windows — they cannot determine which page they are on without reading the content. WCAG 2.2 SC 2.4.2 (Page Titled) is a Level A requirement. Duplicate titles compound the problem for users navigating open tabs. For SPAs, a title that never updates after the initial load means every route is indistinguishable.

## Severity rationale

High because pages without descriptive, unique titles disorient screen reader users navigating multiple tabs and violate WCAG 2.2 SC 2.4.2 at Level A — the most foundational tier of conformance.

## Remediation

Export a `metadata` object from every page in the Next.js App Router with a unique, descriptive title. Follow the `Page Name | Site Name` pattern.

```ts
// app/dashboard/settings/page.tsx
export const metadata = {
  title: 'Account Settings | YourApp',
  description: 'Manage your account preferences, security, and notifications.',
}
```

For pages that derive their title from data (e.g., a project name), use `generateMetadata`:

```ts
export async function generateMetadata({ params }: { params: { id: string } }) {
  const project = await getProject(params.id)
  return { title: `${project.name} | YourApp` }
}
```

For React SPAs without a framework, update `document.title` in a `useEffect` on every route change.

## Detection

- **ID:** `page-title`
- **Severity:** `high`
- **What to look for:** Enumerate every relevant item. Check page metadata for unique titles. In Next.js App Router, look for `metadata.title` exports. For SPAs, verify that the page title updates on route change (via `useEffect` or framework navigation hooks).
- **Pass criteria:** At least 1 of the following conditions is met. Every page has a unique, descriptive title that describes the page's purpose or content. Single-page apps update the title on route change. No generic or empty titles.
- **Fail criteria:** Multiple pages share the same title, or a page title is empty/generic (e.g., "Page 1", "Untitled").
- **Skip (N/A) when:** Never — every web page should have a title.
- **Detail on fail:** Example: `"All pages share title 'My App'. SPA does not update title on navigation"`
- **Remediation:** Set unique titles in metadata:

  ```ts
  // app/about/page.tsx
  export const metadata = {
    title: 'About Us | YourSite',
  }
  ```

  For SPAs, update the title on route change:

  ```tsx
  useEffect(() => {
    document.title = `${currentPage} | MyApp`
  }, [currentPage])
  ```

## External references

- wcag 2.4.2
- section-508 501.1

Taxons: accessibility, findability

HTML version: https://auditbuffet.com/patterns/ab-000105
