Short answer: The lang attribute on the html element, such as <html lang="de">, declares the main language of a page. Screen readers use it to choose pronunciation, browsers use it for translation prompts, hyphenation and fonts, and some search engines use it as a language hint. Google has said it relies on the visible text rather than the lang attribute to detect language, but a wrong value is still a sign of broken templates and hurts accessibility. Set it on every page, and make it match the language of the content.
What the lang attribute is
The lang attribute is a standard HTML attribute that tells software which human language an element’s content is written in. When it is set on the root html element, it applies to the whole page, unless a child element overrides it. The values follow the same language tag rules as hreflang: a language code such as en, fr or lt, optionally followed by a region, as in en-GB or pt-BR.
It is one of the smallest pieces of markup on a page, and it is easy to overlook. Many themes and templates hard-code a value such as lang="en" once, and it stays that way on every translated page. The page looks fine in the browser, so nobody notices.
The MDN reference for the lang attribute describes it as a global attribute, which means it can be used on any element, not only on html.
Who uses the lang attribute
The attribute matters to more software than most people expect:
- Screen readers switch voice and pronunciation rules based on it. A German page marked as English is read aloud with English pronunciation, which makes it hard or impossible to understand. This is why accessibility guidelines require the page language to be declared.
- Browsers use it to decide whether to offer translation, to choose hyphenation rules, to pick appropriate fonts for some scripts, and to format quotation marks and other typographic details in CSS.
- Spell checkers and input tools can use it to choose a dictionary in forms and editable areas.
- Search engines may use it as one hint among several. Google has stated that it determines a page’s language from the visible content and does not rely on the lang attribute. Bing has said it considers the content-language meta tag and other signals, including HTML language attributes, alongside the text itself.
So while the lang attribute is not a ranking factor in the usual sense, it is part of a correctly built multilingual page. It is also a cheap, reliable indicator of whether your templates are language-aware.
lang attribute vs hreflang vs content-language
These three are often confused. They do different jobs and should agree with each other.
| Signal | Where it lives | What it says | Main users |
|---|---|---|---|
| lang attribute | <html lang="de"> |
The language of this page (or element) | Screen readers, browsers, some search engines |
| hreflang | Link tags, sitemap or HTTP header | Which other language versions of this page exist | Search engines choosing which version to show |
| Content-Language | HTTP header or meta http-equiv | The intended audience language of the document | Some search engines, notably Bing |
A German page in a well-built multilingual site would have lang="de" on its html element, a hreflang cluster that includes itself as de, and, if used, a content-language value of de. When these disagree, the page sends mixed signals and something in the set-up is probably broken.
Common lang attribute mistakes
- Hard-coded English on every language. The most frequent problem. The theme header contains
lang="en"orlang="en-US"as fixed text, so French, German and Spanish pages all claim to be English. - Missing attribute. The html element has no lang at all. Accessibility checkers flag this as a failure.
- Underscores instead of hyphens. Values such as
en_UScome from system locales and are not valid language tags. - Country codes used as languages.
lang="se"for Swedish orlang="jp"for Japanese. The correct codes aresvandja. - Mismatch with hreflang. The page is annotated as
dein hreflang but declareslang="en". One of the two is wrong. - The value describes the audience, not the text. A page for Swiss customers written in German should be
deorde-CH, not a code for French or Italian because they are also spoken in Switzerland.
Marking passages in another language
Pages sometimes contain text in more than one language: a quotation, a product name, a legal notice, or a language switcher that lists each language in its own name. The lang attribute can be set on any element to handle this.
- A French quotation inside an English article:
<blockquote lang="fr">…</blockquote>. - A language switcher: each link labelled in its own language, such as
<a href="/de/" lang="de">Deutsch</a>, so screen readers pronounce each name correctly. - A short phrase inside a paragraph:
<span lang="la">…</span>.
This is mainly an accessibility improvement. It does not change how search engines treat the page, but it makes the page easier to use for people who rely on assistive technology.
Pages that are genuinely half in one language and half in another are a different problem. If a German page has large blocks of English text because translation is incomplete, the fix is to finish the translation, not to mark the English parts with lang attributes.
Right-to-left languages and the dir attribute
For Arabic, Hebrew, Persian and Urdu, the lang attribute works together with the dir attribute. A page in Arabic should have <html lang="ar" dir="rtl">. The dir attribute tells browsers to lay out text and interface elements from right to left.
Forgetting dir leads to layouts where punctuation, numbers and mixed Latin text appear in the wrong order, which looks broken to native readers. It is not a direct search signal, but a page that looks broken to its audience is unlikely to perform well.
Setting the lang attribute in WordPress and other CMS
In WordPress, themes should output the attribute with the language_attributes() function in the html tag of header.php, which prints the site language set in Settings, General. Multilingual plugins then change that value per page to match the page’s language.
If your translated pages show the wrong value, check these points in order:
- Open header.php (or the block theme’s template) and look for a hard-coded lang value instead of
language_attributes(). - Check the site language in Settings, General.
- Check the language settings in your multilingual plugin, including the locale assigned to each language.
- Clear page caches, because a cached page from one language can be served for another if caching is misconfigured.
On other platforms the principle is the same: the value must come from the page’s language, not from a fixed string in a template.
Why a wrong lang value is a warning sign
Even if the lang attribute had no effect on search at all, it would still be worth checking, because it tells you something about the rest of the page. A translated page that still declares the original language was usually built from a template that is not language-aware. The same template often has other gaps.
When audits find a hard-coded lang value, the same pages frequently also have:
- Open Graph locale tags that still name the original language, so social previews and some apps treat the page as untranslated.
- Structured data with an
inLanguagevalue, prices or addresses copied from the original version. - Date formats, number formats and currency symbols from the original market.
- Untranslated interface text in menus, buttons, cookie banners and form messages.
- Hreflang or canonical tags generated by a different part of the system that does not know about the translation.
Treat a wrong lang value as a pointer. Fix the attribute, then look at the same template for the other language details that were probably missed at the same time. That is usually where the bigger improvements are.
How to check lang attributes across a site
For a quick check, view the source of one page per language and look at the first html tag. For a site-wide check, a crawler is faster and more reliable, because template differences mean one section can be right and another wrong.
Site SEO AI Audit checks lang attributes on every crawled page as part of its Languages area, alongside hreflang return links, broken language versions and x-default. Problems are weighted by the share of pages they affect, and on WordPress sites the report includes the steps to fix them in wp-admin. You can start with a free audit of your site.
Related reading
- What is hreflang? A plain-English guide for site owners
- hreflang language and region codes: a practical reference
- Image alt text: how to write it for SEO and accessibility
The bottom line
The lang attribute declares the language of a page. It is essential for screen readers and useful for browsers, and some search engines consider it, even though Google relies on the visible text. Set it on every page from the page’s real language, use valid codes, keep it consistent with hreflang, add dir for right-to-left languages, and check it after template or plugin changes.
GYIK
Does Google use the HTML lang attribute?
Google has said it detects the language of a page from its visible content and does not rely on the lang attribute. The attribute still matters for accessibility, browsers and other search engines.
Is lang=”en” wrong on a German page?
Yes. The value should describe the language of the content, so a German page should use lang=”de” or a regional variant such as de-DE. A wrong value makes screen readers mispronounce the text.
Should the lang attribute include a region?
It can, but it is optional. Use a region such as en-GB when it reflects real differences in spelling or vocabulary; otherwise the plain language code is enough.
Do I still need hreflang if my lang attribute is correct?
Yes, if you have multiple language versions. The lang attribute only describes the current page, while hreflang tells search engines which alternate versions exist and who each one is for.
How do I set the lang attribute in WordPress?
Themes should output it with the language_attributes() function in the html tag. WordPress fills it from the site language, and multilingual plugins adjust it for each translated page.


