Rule handbook metadata

Rule
DET.PAGE.LANG · lane deterministic
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.py copies the After example HTML from this handbook page onto the defect fixture, then invoke-det-ruleset-remediation-verify.sh re-audits and expects zero findings for this rule.
  • Production sites: run-website-ux-remediation-loop.sh runs handbook_html_patch (HTML patches in lib/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 as en-US, fr, de) on every full document shell.
  • handbook_page output includes lang="{html_lang}" with default html_lang="en" in layouts.py.
  • chapter_page, product_page, and marketing shells match the same pattern — language is on <html>, not only on inner main or p nodes.
  • Audit metrics report lang: "en" (or the chosen tag); DET.PAGE.LANG produces no findings.
  • Language tag aligns with visible body copy (English handbook pages use en, not a mismatched locale).

Failing signals

  • Missing attribute: <html> with no lang — common when a minimal HTML stub or client-rendered shell omits the root declaration.
  • Empty attribute: <html lang=""> — treated as absent; metrics.lang is falsy.
  • Wrong placement: lang only on <main> or a wrapper div — the check reads document.documentElement only; inner attributes do not satisfy the rule.
  • Generator drift: Python layout sets html_lang but 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)

Forge SDLC — Governed delivery handbook

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)

Forge SDLC — Governed delivery handbook

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.