Issue #105 · important
Issue 105
What is this issue?
This issue checks whether your web pages have a valid lang attribute on the <html> element that declares the page's primary human language.
A passing implementation includes a lang attribute with a valid BCP 47 language tag:
- The attribute must be present on the
<html>element - The value must be a valid language tag (e.g.,
en,en-US,fr,zh-Hans) - The tag should use hyphens (
-) as separators, not underscores (_) - For Chinese, a script subtag should be included (
zh-Hansorzh-Hant)
Example of correct implementation:
<html lang="en">
...
</html>
or for multiple language regions:
<html lang="en-US">
...
</html>
Without a valid lang attribute, search engines may misclassify the page language, preventing proper language-targeted serving via hreflang and breaking screen reader pronunciation.
Why does it matter?
The lang attribute is crucial for SEO, accessibility, and user experience:
- Indexability: Search engines use the
langattribute to understand the page's language and serve it to users in the right locale in search results. - Duplicate content: Incorrect language declarations can cause search engines to treat translated content as duplicate rather than alternate language versions.
- User experience: Screen readers and assistive technologies use the
langattribute to pronounce content correctly. - AI Search / AEO: AI-powered search systems need to understand the language of content to provide accurate answers to users in their preferred language.
- Accessibility: WCAG 3.1.1 requires a valid
langattribute for web accessibility compliance.
Resolving this issue improves your SEO health score by ensuring search engines correctly understand and serve your content to the right audience, and by making your site accessible to users with disabilities.
How to fix it
Follow these steps to implement the lang attribute correctly:
-
Add the
langattribute to your HTML element: Ensure every page has alangattribute on the<html>element:<html lang="en"></html> -
Use valid BCP 47 language tags: Refer to the IANA Language Subtag Registry for valid language tags. Common examples:
en(English)en-US(English - United States)fr(French)fr-CA(French - Canada)zh-Hans(Chinese - Simplified)zh-Hant(Chinese - Traditional)
-
Use hyphens, not underscores: BCP 47 requires hyphens as separators. Correct:
en-US, Incorrect:en_US -
Avoid deprecated codes: Don't use deprecated language codes like
iw(usehe),ji(useyi), orin(useid). -
For Chinese content, include script subtag: Use
zh-Hans(Simplified) orzh-Hant(Traditional) instead of justzh. -
Verify implementation:
- Use the W3C Markup Validation Service to check for errors
- Test with screen readers to ensure proper pronunciation
- Check that search engines correctly identify the page language
Note: If your page has content in multiple languages, the lang attribute should reflect the primary language of the page. Use lang attributes on specific elements for secondary languages.
Examples
Example 1: Correct Implementation
Scenario: A properly configured page with valid lang attribute.
Correct State (Passes):
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>English Page</title>
</head>
<body>
<p>This page is in English.</p>
</body>
</html>
Example 2: Missing Lang Attribute
Scenario: Page has no lang attribute on the html element.
Problematic State (Fails):
<html>
<head>
<meta charset="UTF-8" />
<title>Page Title</title>
</head>
<body>
<p>Content without language declaration.</p>
</body>
</html>
Why it fails: Search engines cannot reliably determine the page language, which may cause incorrect serving in search results.
Corrected State (Passes):
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Page Title</title>
</head>
<body>
<p>Content with language declaration.</p>
</body>
</html>
Example 3: Invalid Lang Attribute Format
Scenario: Lang attribute uses underscore instead of hyphen.
Problematic State (Fails):
<html lang="en_US">
<head>
<meta charset="UTF-8" />
<title>Page Title</title>
</head>
<body>
<p>Content with invalid language tag format.</p>
</body>
</html>
Why it fails: BCP 47 requires hyphens as separators, not underscores. The tag en_US is not valid.
Corrected State (Passes):
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>Page Title</title>
</head>
<body>
<p>Content with valid language tag.</p>
</body>
</html>
Example 4: Deprecated Language Code
Scenario: Page uses deprecated language code.
Problematic State (Fails):
<html lang="iw">
<head>
<meta charset="UTF-8" />
<title>Hebrew Page</title>
</head>
<body>
<p>Content in Hebrew with deprecated language code.</p>
</body>
</html>
Why it fails: The code iw is deprecated. The current BCP 47 code for Hebrew is he.
Corrected State (Passes):
<html lang="he">
<head>
<meta charset="UTF-8" />
<title>Hebrew Page</title>
</head>
<body>
<p>Content in Hebrew with valid language code.</p>
</body>
</html>
Example 5: Ambiguous Chinese Without Script Subtag
Scenario: Chinese page uses zh without script specification.
Problematic State (Fails):
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>Chinese Page</title>
</head>
<body>
<p>Chinese content without script specification.</p>
</body>
</html>
Why it fails: The tag zh is ambiguous because Chinese can be written in Simplified or Traditional script. Search engines need the script subtag to serve the correct variant.
Corrected State (Passes):
<html lang="zh-Hans">
<head>
<meta charset="UTF-8" />
<title>Simplified Chinese Page</title>
</head>
<body>
<p>Chinese content in Simplified script.</p>
</body>
</html>
How PixyScan detects this
PixyScan performs the following checks to detect this issue:
-
HTML parsing: The crawler parses the
<html>element and extracts thelangattribute value. -
Presence check: It checks whether the
langattribute exists on the<html>element. -
Value validation: If the attribute exists, PixyScan:
- Checks if the value is empty
- Validates the value against BCP 47 (IETF RFC 5646) language tag format
- Checks for deprecated language codes
- Verifies that hyphens are used as separators (not underscores)
-
Language detection: The crawler may also:
- Extract visible text content from the page
- Run language detection to compare against the declared
langvalue - Flag mismatches if the detected language differs significantly
-
Pass/Fail determination:
- Passes: If a valid
langattribute is present with a valid BCP 47 language tag - Fails: If the
langattribute is missing, empty, or contains an invalid language tag
- Passes: If a valid
The detection focuses on whether the attribute exists and contains a valid language tag, not on whether the declared language matches the actual content (though mismatches may be flagged as warnings).