Missing Language Attribute
What This Means
The language attribute (lang) tells browsers, screen readers, and search engines what language your content is written in. When the lang attribute is missing from the <html> element or incorrectly applied to content in different languages, screen readers may pronounce words incorrectly, translation tools malfunction, and search engines struggle to serve your content to the right audience.
How the Language Attribute Works
The Problem Without Language Declaration:
<!-- WRONG: No language specified -->
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Our Site</title>
</head>
<body>
<h1>Hello World</h1>
<p>This is English content, but screen readers don't know that!</p>
</body>
</html>
Screen reader impact:
- May use wrong language pronunciation rules
- "Resume" (English) vs "Résumé" (French) sound different
- "Read" (present) vs "Read" (past) need context
- User with French screen reader gets French pronunciation for English words
Correct Implementation:
<!-- CORRECT: Language specified -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Welcome to Our Site</title>
</head>
<body>
<h1>Hello World</h1>
<p>This is English content!</p>
<!-- French section within English page -->
<blockquote lang="fr">
<p>Bonjour le monde!</p>
</blockquote>
</body>
</html>
Impact on Your Business
Accessibility Impact:
- Broken screen reader pronunciation - Users can't understand content
- Poor user experience - Disabled users struggle to use site
- WCAG violation - Fails WCAG 2.1 Level A requirement 3.1.1
- Legal liability - ADA compliance issues
- Lost customers - 15% of users have some form of disability
SEO Consequences:
- Wrong geographic targeting - Google serves content to wrong countries
- Hreflang issues - Multilingual sites don't work properly
- Lower rankings - Search engines can't identify language
- Missed traffic - Users searching in your language don't find you
Internationalization Issues:
- Translation tools fail - Google Translate can't detect language
- Browser features break - Auto-translate, spell-check malfunction
- Font rendering issues - Some languages need specific fonts
- Text direction problems - RTL languages render incorrectly
How to Diagnose
Method 1: View Page Source
Check For:
❌ Missing lang attribute:
<!DOCTYPE html>
<html>
<!-- No lang attribute -->
✅ Correct lang attribute:
<!DOCTYPE html>
<html lang="en">
<!-- Language declared -->
Method 2: Browser DevTools
- Open DevTools (
F12) - Go to Elements tab
- Look at
<html>element - Check attributes panel
Look For:
<html lang="en"> ✅ Good
<html> ❌ Missing
<html lang=""> ❌ Empty
<html lang="english"> ❌ Wrong format (use ISO 639-1 codes)
Method 3: Lighthouse Accessibility Audit
- Open DevTools (
F12) - Go to Lighthouse tab
- Check Accessibility
- Click Generate report
Check For:
Accessibility Issues:
⚠ <html> element does not have a [lang] attribute
Impact: Serious
WCAG: 3.1.1 Language of Page (Level A)
Method 4: WAVE Browser Extension
- Install WAVE Extension
- Visit your page
- Click WAVE icon
Look For:
- "Language missing or invalid" error
- Red icon indicating critical issue
Method 5: W3C Validator
- Visit W3C Validator
- Enter your URL
- Click Check
Check Results:
Warning: Consider adding a lang attribute to the html
start tag to declare the language of this document.
Method 6: Screen Reader Test
- Enable screen reader (VoiceOver, NVDA, JAWS)
- Navigate to page
- Listen to pronunciation
What to Listen For:
- Words pronounced in wrong language
- Jarring accent switches
- Incomprehensible text
General Fixes
Fix 1: Add lang to HTML Element
Basic implementation:
<!-- English -->
<!DOCTYPE html>
<html lang="en">
<!-- French -->
<!DOCTYPE html>
<html lang="fr">
<!-- Spanish -->
<!DOCTYPE html>
<html lang="es">
<!-- German -->
<!DOCTYPE html>
<html lang="de">
<!-- Japanese -->
<!DOCTYPE html>
<html lang="ja">
<!-- Chinese (Simplified) -->
<!DOCTYPE html>
<html lang="zh-CN">
<!-- Chinese (Traditional) -->
<!DOCTYPE html>
<html lang="zh-TW">
<!-- Arabic -->
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<!-- Note: RTL languages also need dir="rtl" -->
Fix 2: Use Region-Specific Language Codes
When you need to specify region:
<!-- US English -->
<html lang="en-US">
<!-- UK English -->
<html lang="en-GB">
<!-- Canadian French -->
<html lang="fr-CA">
<!-- France French -->
<html lang="fr-FR">
<!-- Mexican Spanish -->
<html lang="es-MX">
<!-- Spain Spanish -->
<html lang="es-ES">
<!-- Brazilian Portuguese -->
<html lang="pt-BR">
<!-- Portugal Portuguese -->
<html lang="pt-PT">
Format: language-REGION
- Language: ISO 639-1 (2-letter code)
- Region: ISO 3166-1 (2-letter country code)
Fix 3: Mark Sections in Different Languages
Content with mixed languages:
<!DOCTYPE html>
<html lang="en">
<head>
<title>International Company</title>
</head>
<body>
<!-- Main content in English -->
<h1>Welcome to Our Company</h1>
<p>We operate globally with offices worldwide.</p>
<!-- French testimonial -->
<blockquote lang="fr">
<p>Excellent service! Je recommande vivement cette entreprise.</p>
<footer> - Pierre Dubois</footer>
</blockquote>
<!-- Spanish section -->
<section lang="es">
<h2>Información en Español</h2>
<p>Contáctenos para más información.</p>
</section>
<!-- German quote -->
<p>As the saying goes, <q lang="de">Ordnung muss sein</q>.</p>
</body>
</html>
Fix 4: WordPress Implementation
Theme files (header.php):
<!-- BEFORE: Missing lang -->
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<!-- This outputs lang attribute automatically -->
<!-- Output: -->
<!DOCTYPE html>
<html lang="en-US">
<!-- For multilingual sites using WPML/Polylang: -->
<!-- The plugin automatically sets correct lang per page -->
Manually set if needed:
<!DOCTYPE html>
<html lang="<?php echo get_bloginfo('language'); ?>">
Fix 5: React/Next.js Implementation
import Document, { Html, Head, Main, NextScript } from 'next/document';
class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
React (index.html or public/index.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Dynamically change language in React:
import { useEffect } from 'react';
function App() {
const currentLanguage = 'fr'; // from state/context
useEffect(() => {
document.documentElement.lang = currentLanguage;
}, [currentLanguage]);
return <div>App content</div>;
}
Fix 6: Server-Side Language Detection
Node.js/Express example:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
// Detect user's language from Accept-Language header
const userLang = req.acceptsLanguages(['en', 'fr', 'es', 'de']) || 'en';
res.send(`
<!DOCTYPE html>
<html lang="${userLang}">
<head>
<title>Multilingual Site</title>
</head>
<body>
<h1>Content in ${userLang}</h1>
</body>
</html>
`);
});
Fix 7: Static Site Generators
Jekyll (_layouts/default.html):
<!DOCTYPE html>
<html lang="{{ site.lang | default: 'en' }}">
<head>
<title>{{ page.title }}</title>
</head>
<body>
{{ content }}
</body>
</html>
Hugo (layouts/_default/baseof.html):
<!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}">
<head>
<title>{{ .Title }}</title>
</head>
<body>
{{ block "main" . }}{{ end }}
</body>
</html>
Gatsby (gatsby-ssr.js):
export const onRenderBody = ({ setHtmlAttributes }) => {
setHtmlAttributes({ lang: 'en' });
};
Fix 8: Shopify Theme
theme.liquid:
<!DOCTYPE html>
<html lang="{{ shop.locale }}">
<head>
<title>{{ page_title }}</title>
</head>
<body>
{{ content_for_layout }}
</body>
</html>
Platform-Specific Guides
Detailed implementation instructions for your specific platform:
Verification
After adding language attributes:
Test 1: View Source
- View page source
- Confirm
<html lang="XX">present - Verify correct language code
- Check language-specific sections marked
Test 2: Lighthouse
- Run Lighthouse accessibility audit
- "html element has lang attribute" should pass
- Accessibility score should improve
Test 3: W3C Validator
- Validate HTML
- No language warnings
- Valid language codes used
Test 4: Screen Reader
- Enable screen reader
- Navigate to page
- Listen to pronunciation
- Should use correct language voice
- Multi-language sections should switch voices
Test 5: Browser DevTools
// Check current language
console.log(document.documentElement.lang);
// Output: "en"
// Check all elements with lang
document.querySelectorAll('[lang]').forEach(el => {
console.log(el.tagName, el.lang, el.textContent.substring(0, 50));
});
Common Mistakes
- Using full language names - Use ISO codes (
en, notenglish) - Wrong code format - Use lowercase (
en-US, notEN-us) - Forgetting multi-language content - Mark sections in different languages
- Not updating dynamically - Single-page apps need to update lang attribute
- Incorrect region codes -
en-UKis wrong, useen-GB - Missing from iframe - Iframes need own lang attribute
- Using non-standard codes - Stick to ISO 639-1 codes
- Not considering RTL - Arabic, Hebrew need
dir="rtl"too
Language Code Reference
Common ISO 639-1 language codes:
| Code | Language |
|---|---|
ar |
Arabic |
de |
German |
en |
English |
es |
Spanish |
fr |
French |
hi |
Hindi |
it |
Italian |
ja |
Japanese |
ko |
Korean |
nl |
Dutch |
pl |
Polish |
pt |
Portuguese |
ru |
Russian |
zh |
Chinese |
Full list: ISO 639-1 Codes