HTML lang Attribute Missing
Lighthouse (rule: html-has-lang), axe DevTools (rule: html-has-lang, html-lang-valid, valid-lang), WAVE (Error: Missing language), Pa11y (WCAG2AA.Principle3.Guideline3_1.3_1_1)
Why it matters
Screen readers use the HTML lang attribute to select the correct text-to-speech (TTS) engine and apply the right pronunciation rules, accent, and phoneme set. When the lang attribute is missing or wrong, screen readers guess the language — and guess incorrectly. An English screen reader reading a French page will mispronounce every word. A French TTS engine reading English content will apply French phonetics to English words, making them completely incomprehensible. For Braille display users, the wrong language tag causes the wrong Braille code table to be applied, rendering content unreadable. Additionally, some browsers use the lang attribute to select appropriate fonts for CJK (Chinese-Japanese-Korean) characters. WCAG 3.1.1 is Level A — the most critical requirement level.
Symptoms — what you'll see
If your site has this problem, you may observe any of the following:
- Screen reader reads English content in the wrong language/accent (French TTS for English content)
- Screen reader mispronounces words consistently due to wrong language detection
- Braille output uses wrong Braille code for the content language
- Lighthouse flags "html element does not have a lang attribute"
- axe DevTools reports "html-has-lang" violation
- WAVE shows "No lang attribute" error
- Foreign language quotes or embedded phrases read incorrectly
Common causes
- HTML templates created without including the lang attribute
- CMS themes or boilerplates that have <html> without lang
- Single-page application root templates missing lang in the HTML shell
- Next.js, Nuxt, Gatsby, or similar frameworks with default templates that omit lang
- Copy-pasted HTML snippets that removed the lang attribute
- Multi-language sites that update page content but not the html lang attribute
How to fix it
- 1Add a lang attribute to your <html> element with the appropriate BCP 47 language tag.
- 2For English: <html lang="en">
- 3For US English specifically: <html lang="en-US">
- 4For pages that have mixed language content, add lang attributes to the specific elements containing foreign language text.
- 5In Next.js, set the lang attribute via the <html lang="en"> in the root layout.
- 6In WordPress, the lang attribute is set via the language_attributes() function in header.php.
- 7Validate your language tag at the BCP 47 validator (validator.w3.org/i18n-checker).
- 8For multi-language sites, ensure the lang attribute updates correctly when users switch languages.
Code example
<!-- BROKEN: missing lang attribute -->
<html>
<head>
<meta charset="UTF-8">
<title>My Website</title>
</head>
<!-- BROKEN: French text embedded without lang -->
<p>Our motto is <em>liberté, égalité, fraternité</em>.</p><!-- FIXED: English page with lang attribute -->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Website</title>
</head>
<!-- FIXED: French phrase annotated with lang -->
<p>Our motto is <em lang="fr">liberté, égalité, fraternité</em>.</p>How to test your fix
After applying the fix, verify it works using these testing steps:
- View source on any page and check the opening <html> tag for a lang attribute.
- Run Lighthouse accessibility audit — "html-has-lang" is one of the easiest checks to find.
- Run axe DevTools and look for "html-has-lang" or "html-lang-valid" violations.
- Test with VoiceOver: navigate to the page and listen to the language the TTS uses — does it match the page language?
- For multi-language pages, inspect elements with foreign language content and verify lang attributes on those elements.
- Validate language codes: BCP 47 tags must be valid (e.g., "en-us" should be "en-US" with proper capitalization).
Frequently asked questions
What language code should I use for English?+
"en" is the base language subtag for English and is appropriate for most English-language pages. "en-US" specifies US English (affecting number formatting, date conventions, and some pronunciation). "en-GB" specifies British English. For most websites, "en" is sufficient. Use region subtags only when the regional variant is meaningful for your content.
How do I add lang in Next.js?+
In Next.js App Router, set the lang attribute in your root layout: export default function RootLayout({ children }) { return <html lang="en"><body>{children}</body></html> }. For internationalized Next.js apps using i18n routing, use the detected locale: const { locale } = useRouter(); return <html lang={locale}>.
Does a wrong lang attribute (e.g., lang="en" on a Spanish page) fail WCAG?+
Yes. WCAG 3.1.1 requires the correct language to be declared, not just any language. An incorrect lang attribute is a violation, though automated tools may not always catch it (they check for presence and validity of the tag, not whether it matches the actual content language). Manual review is needed for multi-language sites.
Do I need lang attributes on every paragraph if the page is mostly one language?+
No. The <html lang="..."> covers the primary language of the page. You only need lang attributes on specific elements when their language differs from the page language (WCAG 3.1.2, Level AA). For example, a code snippet in French on an English page should have lang="fr" on the wrapping element.
Does the lang attribute affect SEO?+
For multilingual SEO, the lang attribute works alongside hreflang link tags (for multi-language sites) and helps search engines understand content language. However, the primary purpose is accessibility — helping screen readers and Braille displays select the correct language engine. The SEO benefit is secondary.