squirrelscan
GitHub

lang attribute on <html>: declaring the page's language

Without a lang attribute a screen reader guesses which voice to use and may read the page in the wrong language. squirrel checks it and its format.

What the lang attribute is

<html lang="en"> declares the natural language of a page’s content. A screen reader uses it to pick a pronunciation model, and a browser uses it for hyphenation and for offering translation. Google is explicit that it ignores code-level language declarations and works out the language from the visible content instead, so treat this as an accessibility and browser-behaviour attribute rather than a ranking one.

The value is a BCP 47 language tag: a two or three letter language subtag, optionally followed by a region, as in en, es or en-AU. Use a region subtag only when the regional variant matters; en is more useful than en-US on a page that is not specifically American.

What squirrel checks

The rule runs on every crawled page and reads the lang attribute on the <html> element. It emits a single check named lang-attribute:

  • Warn when the attribute is absent or empty. Message: Missing lang attribute on <html> element. Severity warning, weight 4.
  • Info when the value does not match ^[a-z]{2}(-[A-Z]{2})?$. Message: Lang attribute format: en_US, with the value.
  • Pass when it does. Message: Lang attribute present: en-AU, with the value.

The format test is narrower than BCP 47 allows. It accepts only a lowercase two-letter language with an optional uppercase two-letter region, so valid tags such as pt-BR pass while zh-Hant, en-GB-oxendict and three-letter language subtags are reported as an unexpected format rather than as an error. The informational status reflects that.

Only the <html> element is checked. A lang on a section of the page in another language is not read here.

How to fix it

<html lang="en-AU">

Set it in the base layout, from the same value the site uses to pick its content language. On a multilingual site, render the tag per locale rather than hardcoding one.

Mark passages in another language with their own lang on the element that contains them, so a screen reader switches voice for them.

Rule IDi18n/lang-attribute
CategoryInternationalization
ScopePer-page
Severitywarning
Weight4/10

Enable / disable

Disable this rule

[rules]
disable = ["i18n/lang-attribute"]

Disable all Internationalization rules

[rules]
disable = ["i18n/*"]

Enable only this rule

[rules]
enable = ["i18n/lang-attribute"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

Internationalization findings ship in every audit next to the SEO, performance and agent experience rules. See Fix SEO issues with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com and open the Internationalization section of the report. Each page is reported with the lang value it declares. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close