HTML lang attribute needed on pages
Last updated:
Related Guides
HTML pages must include a valid lang attribute without errors
Every page must declare its primary language on the html element. Without a correct language tag, assistive technologies may mispronounce content or use the wrong voice. This especially affects multilingual users and anyone relying on text-to-speech or braille translation.
Why It Matters
Screen readers pick a voice and pronunciation based on the document language. If the language is missing or wrong, words are spoken incorrectly, names can be distorted, and comprehension drops.
When parts of a page switch languages, tagging those passages lets assistive tech change voices as needed. This reduces cognitive load and helps users who read or listen in multiple languages.
WCAG 2.2 requires the default language of the page to be programmatically determinable (Language of Page) and changes in language to be marked (Language of Parts).
Common Causes
- No lang attribute on the html element.
- Invalid or mistyped code (e.g., en_US, english, sp instead of es, or wrong hyphenation/case).
- Using a country code alone (e.g., US) without a language subtag.
- Not marking language changes within content (quotes, product names, UI labels).
- SPA or dynamic pages that change language but never update documentElement.lang.
- Assuming lang controls direction; missing dir=rtl for right‑to‑left scripts.
How to Fix
- Identify the primary language of the page.
- Use the language used for most of the content. Ignore proper names, code snippets, or brand marks.
- Set the lang attribute on the html element using a valid BCP 47 tag.
- Examples: en, en-US, fr-CA, es-419, pt-BR, zh-Hans, zh-Hant, ar, he.
- Recommendation: lowercase the language subtag (en), uppercase region (US), and include script subtags when relevant (zh-Hans).
- Mark language changes for passages, phrases, or UI pieces.
- Wrap the changed text in an element with lang set to the correct tag.
- Set text direction for right-to-left scripts.
- Use
dir="rtl"on the html element for full RTL pages (e.g., Arabic, Hebrew). - For mixed-direction content, apply
dir="rtl"ordir="auto"on the specific element containing RTL text.
- Use
- Ensure frameworks and dynamic content update lang.
- For SPAs, set document.documentElement.lang when the route or locale changes. Also adjust dir when needed.
- Validate language tags.
- Use the IANA/W3C language subtag references to confirm tags exist and are correctly formed. Avoid invented or legacy codes.
How to Test
DOM/Code check
- Inspect the html element and confirm lang is present and correctly formed (e.g., en-US, not en_US).
- Verify any in-page language changes have lang on the smallest container that holds the changed text.
- For RTL languages, confirm
dir="rtl"on html or on the relevant elements.
Screen reader check
- Desktop: NVDA or JAWS on Windows, VoiceOver on macOS. Read a paragraph and confirm the voice/pronunciation matches the page language. Move focus to a marked foreign phrase and confirm the voice switches.
- Braille: If available, verify correct contraction/translation for the declared language.
Mobile check
- iOS VoiceOver and Android TalkBack: Read a sample paragraph, then a marked foreign phrase. Confirm speech switches language correctly.
Automated checks
- Run axe, WAVE, or Lighthouse to flag missing lang on html.
- Use the W3C Nu HTML Checker and a BCP 47 validator or reference to confirm the tag is valid.
Good Example
!doctype html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<title>Language Demo</title>
</head>
<body>
<p>This page is in American English.</p>
<p>A common Spanish phrase is <span lang="es">buenos días</span>.</p>
<p><span lang="ar" dir="rtl">مرحبا</span> appears right-to-left.</p>
</body>
</html>Bad Example
!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Missing Language</title>
</head>
<body>
<p>Primary language not declared.</p>
<p>Incorrect tag and no hyphen: <span lang="en_US">color</span></p>
<p>Spanish not tagged: buenos días</p>
<p>Arabic without direction set: مرحبا</p>
</body>
</html>Quick Checklist
- html has a lang attribute set to a valid BCP 47 tag.
- The declared language matches the page’s primary content.
- Language changes are marked on the smallest relevant element.
- Use
dir="rtl"for RTL pages or sections;dir="auto"when helpful for mixed content. - Avoid invalid codes (no underscores, no country-only values, no made-up tags).
- SPAs update document.documentElement.lang (and dir) when locale changes.
- Validate tags with trusted references and run automated accessibility checks.