Pages need a language
- Rule:
axe/html-has-lang - Checks: <html> element must have a lang attribute
- WCAG: 3.1.1
- Fix class:
content: A fix needs authored text.
Who it affects
Section titled “Who it affects”- People who use a screen reader or a braille display, most of them blind.
- People with cognitive, learning or attention disabilities.
How to fix it
Section titled “How to fix it”The <html> element has no lang, or it is empty
Section titled “The <html> element has no lang, or it is empty”Add lang with the language tag of the page’s main content, such as en, es or ja. Decide it from the language the content is written in.
<html lang="en"> <head> <title>Plans - Acme</title> </head> <body> <main> <h1>Plans</h1> </main> </body></html>The <html> element has only xml:lang
Section titled “The <html> element has only xml:lang”Add lang with the same value. In a page served as HTML, xml:lang has no effect; keep it only beside a matching lang when the page is also served as XHTML.
A template or a script leaves lang unset
Section titled “A template or a script leaves lang unset”Set lang in the HTML the server sends, from the language each page is in. If the page switches language in place, update lang with the content.
Fixes that fail
Section titled “Fixes that fail”Hard-coding lang="en" in a template that serves pages in several languages
Section titled “Hard-coding lang="en" in a template that serves pages in several languages”axe accepts it, but screen readers then read the other languages with English pronunciation. Set it from each page’s own language.
In React
Section titled “In React”The part of the fix that differs in React, in its syntax. The rest of the guidance holds.
A client-rendered app has no lang on the <html> element in index.html
Section titled “A client-rendered app has no lang on the <html> element in index.html”Add lang to <html> in index.html. The app renders inside <body>, so no component renders that element.
A root layout component renders the <html> element
Section titled “A root layout component renders the <html> element”Set lang on the <html> it renders, from the page’s language.
function RootLayout({ locale, children }) { return ( <html lang={locale}> <body>{children}</body> </html> );}The app switches language without reloading the page
Section titled “The app switches language without reloading the page”Set document.documentElement.lang in an effect that runs when the language changes.
function LanguageSync({ locale, children }) { useEffect(() => { document.documentElement.lang = locale; }, [locale]); return children;}Fixes that fail in React
Section titled “Fixes that fail in React”Setting lang on the root <div> the app renders
Section titled “Setting lang on the root <div> the app renders”axe still reports the page, because it checks <html>, and the <head>, with the page title, stays outside that <div>.
More on the rule
Section titled “More on the rule”axe-core’s documentation of the rule
CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.