Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.
HTMLHigh

Set the page lang attribute

The <html> element must have a lang attribute with a valid BCP 47 language code so screen readers, translation tools, and search engines know the primary language of the page.

Utilities
Quick take
Typical fix time 5 min
  • The `<html>` element must have a `lang` attribute — WCAG 2.1 SC 3.1.1 (Language of Page, Level A)
  • The value must be a valid BCP 47 language tag: `en`, `en-US`, `fr`, `zh-Hant`, `ar`, etc.
  • Use `lang` on individual elements to indicate language changes within the page — WCAG 2.1 SC 3.1.2 (Level AA)
  • The `lang` attribute affects screen reader pronunciation, spell checking, hyphenation, and browser translation
  • An empty `lang=''` is treated as unknown language — equivalent to having no `lang` attribute
Why it matters: Screen readers select the correct text-to-speech voice and pronunciation engine based on the `lang` attribute. Without it, VoiceOver defaults to the user's system language, and NVDA uses its default voice — both may mispronounce words in other languages, making content unintelligible. French text read with an English voice profile is incomprehensible. The `lang` attribute also enables browser translation features (Chrome's Translate), hyphenation algorithms (CSS `hyphens: auto`), and correct spell checking. This is a WCAG Level A requirement — the most fundamental accessibility baseline.

Rule Details

The lang attribute on the <html> element identifies the primary language of a web page. It is used by screen readers, browsers, search engines, and translation services to process content correctly.

Code Example

<!-- ✅ Correct: English page -->
<!DOCTYPE html>
<html lang="en">
 
<!-- ✅ Correct: American English -->
<!DOCTYPE html>
<html lang="en-US">
 
<!-- ✅ Correct: French -->
<!DOCTYPE html>
<html lang="fr">
 
<!-- ✅ Correct: Arabic (right-to-left) -->
<!DOCTYPE html>
<html lang="ar" dir="rtl">
 
<!-- ❌ Incorrect: missing lang attribute -->
<html>
 
<!-- ❌ Incorrect: full language name (not a BCP 47 code) -->
<html lang="english">
 
<!-- ❌ Incorrect: empty lang attribute -->
<html lang="">

Why It Matters

  • Screen Readers: VoiceOver and NVDA use lang to select the speech synthesis engine — wrong language means incomprehensible pronunciation.
  • Browser Translation: Chrome's auto-translate uses lang to detect the source language and offer translation.
  • CSS Hyphenation: hyphens: auto in CSS relies on the lang attribute to apply correct hyphenation rules.
  • Spell Checking: Browser spell check and tools like Grammarly use lang to select the dictionary.
  • Search Engines: Google uses lang to target content to the correct regional audience in search results.

Language Changes Within a Page

When a page contains content in multiple languages, mark each language change with lang on the containing element:

<html lang="en">
<body>
  <p>The French say <span lang="fr">bonjour</span> as a greeting.</p>
 
  <!-- Block-level language change -->
  <blockquote lang="de">
    <p>Ich denke, also bin ich. — René Descartes</p>
  </blockquote>
</body>
</html>

Common BCP 47 Language Codes

LanguageCode
Englishen
English (US)en-US
English (UK)en-GB
Frenchfr
Spanishes
Germande
Japaneseja
Koreanko
Simplified Chinesezh-Hans
Traditional Chinesezh-Hant
Arabicar
Portuguese (Brazil)pt-BR
Hindihi

Framework Examples

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
const rtlLocales = new Set(['ar', 'fa', 'he', 'ur'])
 
export function LocaleLayout({
  locale,
  children,
}: {
  locale: string
  children: React.ReactNode
}) {
  return (
    <html lang={locale} dir={rtlLocales.has(locale) ? 'rtl' : 'ltr'}>
      <body>{children}</body>
    </html>
  )
}

Best Practices

  • Set the language on the root <html> element even when the whole site uses one locale.
  • Prefer region or script subtags such as en-GB or zh-Hant when they materially affect pronunciation, spelling, or font selection.
  • Add nested lang attributes only where the language actually changes.
  • Validate the final rendered HTML rather than assuming framework metadata APIs emitted the correct root attribute.

Standards

  • Use WCAG 2.1 SC 3.1.1: Language of Page as the standard for the final rendered HTML and browser-facing behavior.
  • Use WCAG 2.1 SC 3.1.2: Language of Parts as the standard for the final rendered HTML and browser-facing behavior.
  • Use HTML Living Standard: The lang attribute as the standard for the final rendered HTML and browser-facing behavior.

Verification

Automated Checks

  • Inspect the final rendered HTML in the browser or page source to confirm the rule is satisfied.
  • Validate the affected markup with browser tooling or an HTML validator where appropriate.
  • Test one representative route or template that uses the pattern.
  • Re-check shared components that emit the same markup so the fix is consistent.

Manual Checks

  • Verify the rendered browser behavior manually on representative routes and supported browsers so the user-facing outcome matches the rule.

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Inspect the `<html>` element in the page source. Verify: (1) a `lang` attribute is present; (2) its value is non-empty; (3) its value is a valid BCP 47 language code matching the primary language of the page content (e.g., `en` for English, `fr` for French, `zh-Hant` for Traditional Chinese). Flag: missing `lang`, empty `lang=''`, language codes using full names instead of codes (e.g., `lang='english'` is invalid), and mismatches where the declared language does not match the actual content language. For multilingual pages, also check for `lang` changes on block-level elements containing content in a different language.

Fix

Auto-fix issues

Add or correct the `lang` attribute on the `<html>` element: `<html lang='en'>` for English, `<html lang='fr'>` for French, `<html lang='es'>` for Spanish, `<html lang='de'>` for German, `<html lang='ja'>` for Japanese, `<html lang='zh-Hans'>` for Simplified Chinese, `<html lang='zh-Hant'>` for Traditional Chinese, `<html lang='ar'>` for Arabic. For content sections in different languages, add `lang` to the containing block element. Validate language codes against the IANA Language Subtag Registry.

Explain

Learn more

WCAG 2.1 SC 3.1.1 (Language of Page, Level A) requires that the default human language of each web page can be programmatically determined. The `lang` attribute on `<html>` fulfills this requirement. The value must be a BCP 47 language tag — a standardized system of subtags that identifies language, script, and region. The primary language subtag (e.g., `en`, `fr`) is required; region subtags (e.g., `en-US`, `fr-CA`) are optional but useful for dialect-specific pronunciation and spell checking. SC 3.1.2 (Language of Parts, Level AA) extends this to inline language changes within a page.

Review

Code review

Review templates, server-rendered HTML, and shared components that output markup related to Set the page lang attribute. Flag exact elements, attributes, and routes where the rendered HTML violates the rule.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

Nu Html Checker
validator.w3.orgTool
axe DevTools
deque.comTool

Rules that often go hand-in-hand with this one.

Declare UTF-8 character encoding

The charset (UTF-8) is declared correctly as the first element in the head.

HTML
Set the responsive viewport meta tag

The viewport meta tag is declared correctly for responsive design.

HTML

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385