No language declared on the html element
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 Is This Important
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 XeoPix Detects This
XeoPix 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, XeoPix:
- 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).
How To Fix
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.
What We Store
Storage Level
Page Level — This issue is evaluated for each individual URL.
Database Table / Prisma Model
PageHtmlHeadAudit
Stored Fields
| Field | Type | Description |
|---|---|---|
| htmlLang | String? | The lang attribute value from the html tag |
Detection Dependencies
- The following data sources are required to evaluate this issue:
- HTML Document — The crawler parses the HTML tag to extract the lang attribute
- HTML Tag Parsing — The
<html>tag’s lang attribute is extracted
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>Unit Test
Test File
__tests__/seo-audit-checks/htmlHeadTags/issue-105-html-lang-xx.test.js
Purpose
Validates the detection of a missing lang attribute on the <html> element. Ensures pages are flagged when the lang attribute is absent, and not flagged when it is present regardless of value.
Tested Function
runHtmlHeadTags() from toggleGroups/htmlHeadTags.js
Issue Information
- Issue Number: 105
- Issue Code:
HTML_LANG_XX - Toggle Group:
htmlHeadTags
Test Scenarios
Positive Test Cases
- Page has
<html lang="en">— no issue reported - Page has
<html lang="en-US">(with country code) — no issue reported - Page has
<html lang="">(empty string but attribute present) — no issue reported - Page has
<html lang="en">with malformed HTML structure — no issue reported, no crash - Lang attribute with whitespace (
lang=" en ") — no issue reported - Lang attribute with special characters (
lang="zh-CN") — no issue reported
Negative Test Cases
- Page has
<html>without alangattribute — issue reported with message"HTML lang attribute is missing"
Boundary Cases
None present.
Edge Cases
- Empty HTML (
<html></html>): issue reported (lang attribute is missing) - Malformed HTML: function handles without crashing
- Whitespace handling: lang value with surrounding whitespace is treated as valid
- Empty lang attribute:
lang=""is considered present, so no issue reported
Expected Outcome
Pass
The issue should be reported when:
- The
<html>element has nolangattribute at all - The HTML is empty (
<html></html>without a<head>)
Fail
The issue should not be reported when:
- The
langattribute is present with any value (including empty string) - The
langattribute contains a valid language tag (e.g.,en,en-US,zh-CN) - The
langvalue contains extra whitespace
Validation
- Correct detection of missing
langattribute on<html>element - Correct handling of present
langattribute with any value - Graceful handling of malformed HTML
- Whitespace-tolerant attribute value parsing
- Cache mechanism prevents duplicate issue entries on repeated calls
Related Production Files
toggleGroups/htmlHeadTags.jsissueCodes.js
Coverage Summary
- Positive cases: 5 (en, en-US, empty lang, whitespace, zh-CN)
- Negative cases: 1 (missing lang attribute)
- Edge cases: 3 (empty HTML, malformed HTML, empty lang attribute)
- Cache validation: 1
References
- Language tags in HTML and XML — W3C
- Language Subtag Registry — IANA
- lang attribute — MDN