Screen readers depend on the lang attribute to select the correct language engine for text-to-speech pronunciation. Without it, a screen reader may attempt to pronounce English content using French or Japanese pronunciation rules — producing incomprehensible audio for users who are blind or have low vision. WCAG 2.2 SC 3.1.1 (Language of Page) is a Level A requirement: the lowest, most foundational conformance level. Section 508 (2018 refresh) 504.2 also mandates language identification. A missing lang attribute is an automatic WCAG failure that makes the page non-compliant with accessibility law in the US, EU, and most jurisdictions.
Medium because the impact is targeted — screen reader users bear the full cost of incorrect language detection, while sighted users are unaffected — but it represents a clear WCAG Level A failure.
Set the lang attribute on the root <html> element with a valid BCP 47 language code:
<html lang="en">
In Next.js App Router, set it in app/layout.tsx:
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
For multi-language sites, set lang dynamically based on the current locale: lang={params.locale}. Common codes: en (English), es (Spanish), fr (French), de (German), pt (Portuguese), ja (Japanese), zh (Chinese).
ID: site-health-check.accessibility-mobile.html-lang
Severity: medium
What to look for: Extract the <html> opening tag from the HTML document. Count all lang attributes present in the document (on <html> and any child elements). Check for the presence of a lang attribute on <html>. If present, extract its value and verify it matches a valid BCP 47 language tag format (2-3 letter language code, optionally followed by a region code, e.g., en, en-US, fr, zh-Hans). The value must be at least 2 characters long.
Pass criteria: The <html> tag has a lang attribute with a non-empty value that is at least 2 characters long and follows the BCP 47 language tag format (e.g., en, en-US, fr). Report the actual language code found.
Fail criteria: No lang attribute on <html>, or the value is empty, or the value is a single character or obviously invalid (e.g., lang="x").
Skip (N/A) when: The response Content-Type is not HTML (e.g., JSON API, XML).
Detail on fail: "<html> tag has no lang attribute — screen readers cannot determine the page language"
Remediation: The lang attribute on <html> tells screen readers which language to use for pronunciation. Without it, screen readers guess (often incorrectly). Set it on your root HTML element:
<html lang="en">
In Next.js App Router, set it in app/layout.tsx: <html lang="en">. For multi-language sites, set it dynamically based on the locale. Valid codes: en (English), es (Spanish), fr (French), de (German), ja (Japanese), zh (Chinese).