Skip to content
Browse all guides

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-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 does it matter?

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 to fix it

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.

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:

  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, 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)
  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).

References