3.1.1 Language of Page

Level: A | Principle: Understandable | Since: WCAG 2.0 | Automation: Full (axe-core)


What This Means

The primary language of the page must be declared in the <html> tag using the lang attribute. This tells screen readers which pronunciation rules to use, helps translation tools identify the language, and enables browsers to apply correct text rendering.

Who This Affects

  1. Screen reader users — without a lang attribute, the screen reader guesses the language, often incorrectly. An English page read with French pronunciation is unintelligible.
  2. Translation tool users — Google Translate and similar tools use the lang attribute to detect source language
  3. Search engines — language declaration helps with correct indexing

Common Pitfalls

1. Missing lang attribute entirely

<!-- Bad -->
<html>
  <head>...</head>
  <body>...</body>
</html>

<!-- Good -->
<html lang="en">
  <head>...</head>
  <body>...</body>
</html>

2. Invalid language code

<!-- Bad: "english" is not a valid BCP 47 tag -->
<html lang="english">

<!-- Good -->
<html lang="en">

3. Wrong language

<!-- Bad: page is in French but declared as English -->
<html lang="en">
  <body>Bienvenue sur notre site...</body>
</html>

<!-- Good -->
<html lang="fr">
  <body>Bienvenue sur notre site...</body>
</html>

How to Fix

Add the correct lang attribute to the <html> element. Use BCP 47 language tags:

| Language | Tag | |----------|-----| | English | en | | English (US) | en-US | | French | fr | | Spanish | es | | German | de | | Japanese | ja | | Chinese (Simplified) | zh-Hans | | Arabic | ar | | Hindi | hi |

<html lang="en">

In Next.js, this is set in the root layout:

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

How to Test

  1. Right-click the page, select "View Page Source" (Ctrl+U / Cmd+Option+U), and look at the opening <html> tag.
  2. Verify it has a lang attribute with a valid BCP 47 code matching the page's primary language (e.g. lang="en", lang="fr").
  3. Open a screen reader (VoiceOver: Cmd+F5, NVDA: Ctrl+Alt+N) and confirm it pronounces content in the correct language.
  4. Pass: The <html> element has a valid lang attribute matching the page's language.
  5. Fail: Missing lang attribute, empty value, invalid code, or wrong language declared.

axe-core Rules

| Rule | What It Checks | |------|---------------| | html-has-lang | <html> must have a lang attribute | | html-lang-valid | lang value must be a valid BCP 47 tag | | html-xml-lang-mismatch | lang and xml:lang must match |

Sources

  1. W3C WCAG 2.2 — Understanding 3.1.1
  2. axe-core: html-has-lang
  3. BCP 47 Language Tags