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.
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.
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.
// 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:
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.
ID: accessibility-wcag.operable.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:
// app/about/page.tsx
export const metadata = {
title: 'About Us | YourSite',
}
For SPAs, update the title on route change:
useEffect(() => {
document.title = `${currentPage} | MyApp`
}, [currentPage])