Skip to Content

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-Hans or zh-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 lang attribute 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 lang attribute 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 lang attribute 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:

  1. HTML parsing: The crawler parses the <html> element and extracts the lang attribute value.

  2. Presence check: It checks whether the lang attribute exists on the <html> element.

  3. 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)
  4. Language detection: The crawler may also:

    • Extract visible text content from the page
    • Run language detection to compare against the declared lang value
    • Flag mismatches if the detected language differs significantly
  5. Pass/Fail determination:

    • Passes: If a valid lang attribute is present with a valid BCP 47 language tag
    • Fails: If the lang attribute is missing, empty, or contains an invalid language tag

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:

  1. Add the lang attribute to your HTML element: Ensure every page has a lang attribute on the <html> element:

    <html lang="en"></html>
  2. 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)
  3. Use hyphens, not underscores: BCP 47 requires hyphens as separators. Correct: en-US, Incorrect: en_US

  4. Avoid deprecated codes: Don’t use deprecated language codes like iw (use he), ji (use yi), or in (use id).

  5. For Chinese content, include script subtag: Use zh-Hans (Simplified) or zh-Hant (Traditional) instead of just zh.

  6. 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

FieldTypeDescription
htmlLangString?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 a lang attribute — 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 no lang attribute at all
  • The HTML is empty (<html></html> without a <head>)

Fail

The issue should not be reported when:

  • The lang attribute is present with any value (including empty string)
  • The lang attribute contains a valid language tag (e.g., en, en-US, zh-CN)
  • The lang value contains extra whitespace

Validation

  • Correct detection of missing lang attribute on <html> element
  • Correct handling of present lang attribute with any value
  • Graceful handling of malformed HTML
  • Whitespace-tolerant attribute value parsing
  • Cache mechanism prevents duplicate issue entries on repeated calls
  • toggleGroups/htmlHeadTags.js
  • issueCodes.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

Last updated on