Declare The Document Language On The JSX html Element
ID |
javascript.jsx_lang_attribute |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
accessibility, jsx, reliability |
Description
Reports a JSX <html> element that declares no document language: no lang attribute at all, or
one whose value is statically empty.
Rationale
The document language tells a screen reader which voice and pronunciation rules to use, a spell-checker and a translation tool which dictionary to load, and the browser which language-specific typography to apply. Without it every one of them falls back to a guess, and the guess is usually the reader’s locale rather than the page’s.
A React application reaches the <html> element from a shell component — a Next.js document, a
Remix root route, a Gatsby HTML template — so the attribute has to be written in JSX rather than
in a static template. That is why the JSX dialect needs its own check.
The tag name is matched case-sensitively, because JSX uses case to separate a DOM tag from a
component: <html> is the element, <Html> is the component wrapping it, whose rendered markup
this scanner cannot see. A computed value satisfies the rule — only a statically blank one is
reported, since that is the spelling that reaches the DOM empty — and an element that spreads an
object into its attributes is left alone, because lang may arrive at runtime.
<html><body /></html> // FLAW - no language at all
<html lang=""><body /></html> // FLAW - present but empty
<html lang="en"><body /></html> // OK
<html lang={locale}><body /></html> // OK - computed, not knowable here
<Html><body /></Html> // OK - a component, markup unknown
Remediation
Add lang to the JSX <html> element with the page’s primary language as a BCP 47 tag
(lang="en", lang="es-ES"). When the language is chosen at runtime, pass it in
(lang={locale}); any declared value satisfies the rule. Mark a language change inside the page
with lang on the element that contains it, not on <html>.