Rule handbook metadata
- Rule
DET.PAGE.LANG· lanedeterministic- Page status
- current
- page_version
44c6f35dae6a383cc76fab9c0dca814bfe8c1309ffa6bd28a6473d44f81cad9e- generated_at
- 2026-05-25T14:32:00.000Z
- registry_fingerprint
2ce40848effce579d3e4879f6ca85535183a14db201870a6c007da424624550c
How this rule is fixed
Pilot deterministic fixer: handbook_after · harness mode standalone · verify expect_rule_clean.
- Harness:
apply-harness-fixture-remediation.pycopies the After example HTML from this handbook page onto the defect fixture, theninvoke-det-ruleset-remediation-verify.shre-audits and expects zero findings for this rule. - Production sites:
run-website-ux-remediation-loop.shrunshandbook_html_patch(HTML patches inlib/ux-deterministic-fixers/fixers/patches/) before invoking the Cursor agent when the quality gate still fails.
Detection module: docs/design/ux-audit/deterministic-design-rules.md#det-page-lang. Scroll down for Before / After examples and Evidence and remediation steps.
Purpose
Screen readers, browser translation, spell-check, and hyphenation all use the document language on the root <html> element. Without it, assistive tech may guess wrong pronunciation, and mixed-language pages lose a reliable default for embedded content.
Kitchen Sink layouts (handbook_page, chapter_page, product_page, landing_page, showcase shells) emit lang from Python — typically html lang="en" via the html_lang parameter on handbook_page. Consumer site generators should pass the same value they use for visible copy and SEO og:locale hints.
This deterministic rule runs in the metrics phase. The crawler reads document.documentElement.getAttribute('lang'). A page passes when that attribute is present and non-empty (any valid BCP 47 tag, e.g. en, en-US). A page fails when lang is missing or empty.
Plan: Decide the primary locale per site SKU before shipping HTML. Do: Set html_lang in layout calls and verify generated website/ output. Check: metrics.lang is truthy in audit output. Adjust: Add lang on the root element in templates, partials, or SPA shells that currently emit bare <html>.
Passing signals
- Root element is
<html lang="en">(or another declared tag such asen-US,fr,de) on every full document shell. handbook_pageoutput includeslang="{html_lang}"with defaulthtml_lang="en"inlayouts.py.chapter_page,product_page, and marketing shells match the same pattern — language is on<html>, not only on innermainorpnodes.- Audit metrics report
lang: "en"(or the chosen tag);DET.PAGE.LANGproduces no findings. - Language tag aligns with visible body copy (English handbook pages use
en, not a mismatched locale).
Failing signals
- Missing attribute:
<html>with nolang— common when a minimal HTML stub or client-rendered shell omits the root declaration. - Empty attribute:
<html lang="">— treated as absent;metrics.langis falsy. - Wrong placement:
langonly on<main>or a wrapperdiv— the check readsdocument.documentElementonly; inner attributes do not satisfy the rule. - Generator drift: Python layout sets
html_langbut a consumer override strips it during post-processing or static export. - Auditor evidence: "The document lang attribute is missing." with
<html lang> not found.
Before example
Before (failing example)
Methodology
Governed human + agent delivery
English prose with no root language declaration.
Outcome
Screen readers cannot infer document language from the html root.
Failing KS markup: handbook-style shell mirrors handbook_page anatomy (forge-aurora, skip link, sidebar, main#main) but the root omits lang, so assistive tech has no document default.
After example
After (passing example)
Methodology
Governed human + agent delivery
Document language matches English body copy.
Outcome
Assistive tech and translation tools read lang from the html root.
Passing KS markup: same handbook shell with html lang="en" as emitted by handbook_page when html_lang="en" is passed through the layout.
Evidence and remediation
| Evidence | Meaning | Remediation |
|---|---|---|
metrics.lang empty in crawl JSON |
Root lang missing or blank |
Add <html lang="en"> (or site locale) in the layout template |
| Finding: document lang attribute is missing | lang.check.js failed |
Set html_lang on handbook_page / other layouts.py callers; rebuild consumer website/ |
Raw HTML lacks lang= on first <html> |
Post-build regression | Fix generator or export step that strips attributes |
Kitchen Sink: Pass html_lang="en" (or the handbook locale) into handbook_page(..., html_lang=...). Confirm generator/build-showcase.py and consumer builds emit lang on the first line of the document element.
Consumer sites: After layout fixes, run python3 generator/build-site.py (or handbook build), then re-audit. Spot-check: curl -s … | head -n 3 should show <html lang="…">.
Harness: generator/build_rule_defect_fixtures.py and auditor-tests/invoke-det-ruleset-harness.sh --only-rule DET.PAGE.LANG for regression. Implementation: tools/website-ux-auditor/design-rules/deterministic/page/lang.check.js.