Missing Language Attribute
Your HTML doesn't declare what language it's in. Screen readers are guessing — and guessing badly.
What is this?
Imagine calling a French restaurant and they answer the phone in Mandarin. You would be confused. Now imagine switching to French and them still replying in Mandarin. That is what happens when your HTML page does not declare its language — screen readers have to guess, and when they guess wrong, they pronounce everything with the wrong accent, rhythm, and phonetics. English text read with Japanese pronunciation rules is incomprehensible.
The lang attribute on your <html> tag tells browsers and assistive technology what language your content is written in.
Why it matters
- For your visitors: Screen readers use the
langattribute to load the correct pronunciation engine. Without it, a French screen reader encountering English text will try to pronounce "through" using French phonics. The result is gibberish. This affects every single word on the page. - For your business: The
langattribute also affects browser auto-translation, spell checking, hyphenation, and search engine language detection. Missing it means browsers may translate your already-English page into English, or serve it to the wrong audience. - The standard: WCAG 3.1.1 (Language of Page) requires that the default language of each web page is programmatically determinable. This is a Level A requirement — the most basic level.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Cool App</title>
</head>
<body>
<p>Welcome to my site.</p>
</body>
</html><!DOCTYPE html>
<html>
<!-- Screen reader: "Is this English? French? Let me guess..." -->
<head>
<title>My Cool App</title>
</head>
<body>
<p>Welcome to my site.</p>
</body>
</html>How to fix it
React / Next.js
In Next.js App Router, set the lang attribute in your root layout.
// src/app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
// Set the language here — "en" for English
<html lang="en">
<body>{children}</body>
</html>
);
}If your site supports multiple languages, set it dynamically:
// src/app/[locale]/layout.tsx
export default function LocaleLayout({
children,
params,
}: {
children: React.ReactNode;
params: { locale: string };
}) {
return (
<html lang={params.locale}>
<body>{children}</body>
</html>
);
}For content in a different language than the rest of the page, use lang on that specific element:
<p>
The French word for cat is <span lang="fr">chat</span>.
</p>Plain HTML
<!DOCTYPE html>
<!-- Set the primary language of the page -->
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Website</title>
</head>
<body>
<h1>Welcome</h1>
<!-- For content in a different language, use lang on the element -->
<blockquote lang="fr">
<p>La vie est belle.</p>
</blockquote>
<!-- Common language codes:
en = English
en-US = American English
en-GB = British English
es = Spanish
fr = French
de = German
ja = Japanese
zh = Chinese
ar = Arabic (also add dir="rtl" for right-to-left)
-->
</body>
</html>Common mistakes:
- Using the wrong code:
lang="english"is wrong — uselang="en" - Forgetting regional variants:
lang="en-GB"helps screen readers use British pronunciation - Not marking up foreign phrases: if you quote text in another language, wrap it with the correct
lang
This is a one-line fix with outsized impact. The cat finds it baffling how many sites ship without
it. Add lang="en" to your HTML tag and move on with your life.
How the cat scores this
The cat checks the <html> element for a lang attribute. If it is missing, empty, or contains an invalid language code, the cat flags it. The cat also checks for a valid BCP 47 language tag (like "en", "en-US", "fr", "de") — made-up values like "english" or "1" are flagged. For multilingual content, the cat checks whether inline content in other languages is properly marked up.
Further reading
- WebAIM: Document Language — how language attributes affect accessibility
- WCAG 3.1.1: Language of Page — the standard
- IANA Language Subtag Registry — the complete list of valid language codes