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 ID | i18n/lang-attribute |
| Category | Internationalization |
| Scope | Per-page |
| Severity | warning |
| Weight | 4/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.
Related rules
- i18n/hreflang: the tags that connect this page to its other language versions.
- a11y/html-lang-valid: the accessibility check over the same attribute.
- core/charset: the other declaration in the same part of the document.
- content/mojibake: what a wrong encoding does to non-English text.
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
- The lang global attribute, MDN
- Declaring language in HTML, W3C Internationalization
- Managing multi-regional and multilingual sites, Google Search Central
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.