---
title: "Hreflang vs the HTML lang attribute: what each one does"
description: "The lang attribute says what language this page is in; hreflang points to the page in other languages. Who reads each, valid values, and both in one head."
url: "https://www.langrelay.com/blog/hreflang-vs-html-lang"
---

1. [Home](https://www.langrelay.com/)
2. [Blog](https://www.langrelay.com/blog)
3. Hreflang vs the HTML lang attribute: what each one does

ArticleMultilingual SEO

# Hreflang vs the HTML lang attribute: what each one does

The lang attribute says what language this page is in; hreflang points to the page in other languages. Who reads each, valid values, and both in one head.

[Chris Jayden](https://www.langrelay.com/about)

Founder

Published

6 October 2026

Reading time

6 min read

![Two boatwomen pass a basket of vegetables on a misty dawn lake, one boat's canopy patterned with green and orange leaf tiles.](https://www.langrelay.com/_emdash/api/media/file/01M4ET4V0YWBT3VMSZX0KTY5AF.webp)

On this page

1. What the lang attribute does
2. What hreflang does
3. The two side by side
4. Valid values, and where they differ
5. Do lang and hreflang have to match?
6. Does Google use lang to detect a page's language?
7. Both in one head
8. Both attributes on a language switcher
9. How LangRelay sets both
10. How to check a live page

The `lang` attribute on the `<html>` element states the language this page is written in. Browsers, screen readers and spell checkers read it. `hreflang` sits on `<link rel="alternate">` tags and points to the same page in other languages, so that a search engine can show each searcher the right URL. A translated page needs both: `lang` set to its own language, and an hreflang set that lists every version. Neither one replaces the other, and Google says it uses neither to work out what language a page is in.

## What the lang attribute does

MDN describes `lang` as the attribute that "helps define the language of an element". Its value is a single BCP 47 language tag such as `en`, `nl` or `pt-BR`. Child elements inherit it, so putting it on `<html>` covers the whole document. An empty value sets the language to unknown, and a tag that is not valid BCP 47 sets it to invalid.

The audience is software that has to render or speak the text. The W3C's explanation of WCAG success criterion 3.1.1, Language of Page, lists what goes right when the language is declared: screen readers load the correct pronunciation rules, visual browsers display characters and scripts correctly, and media players show captions correctly. That criterion is Level A, the lowest WCAG conformance level, which is why accessibility checkers treat a missing `lang` as a real fault. Deque's axe rule `html-has-lang` rates its user impact as serious.

Two practical rules come from the W3C Internationalization pages:

- Put `lang` on `<html>`, not on `<body>`. The body does not cover the `<title>` and other text inside `<head>`.
- Do not declare the page language with `<meta http-equiv="Content-Language">`. The W3C advises against it, and says the in-page attribute overrides any language information sent in the HTTP header.

`lang` also works on smaller elements. A Dutch page that quotes a German customer can wrap the quote in `<span lang="de">`, and a screen reader switches pronunciation for those words. WCAG's criterion 3.1.2, Language of Parts, asks for exactly this.

## What hreflang does

`hreflang` is an attribute of links. The HTML standard says it "gives the language of the linked resource" and that it is "purely advisory": a browser must judge a page's language from the page itself once it fetches it, never from the link that led there. Combined with `rel="alternate"`, an `hreflang` value that differs from the current document's language marks the linked page as a translation.

Search engines are where it does its work. Google uses a set of `<link rel="alternate" hreflang="...">` tags to understand that several URLs are versions of one page, and then shows the version that fits the searcher's language and region. Every version carries the full set, including a line for itself, and every pair has to point at each other or Google ignores the tags. Our [hreflang guide](https://www.langrelay.com/guides/hreflang) goes through those rules in detail.

## The two side by side

|  | `lang` | `hreflang` |
| --- | --- | --- |
| Where it goes | `<html>`, and any element whose text is in another language | `<link rel="alternate">` in the head, `<a>` links, sitemap entries and HTTP `Link` headers |
| What it describes | The language of this element's content | The language of the page at the other end of the link |
| Who reads it | Browsers, screen readers, spell checkers, caption players | Search engines choosing which URL to show |
| Values in HTML | Any valid BCP 47 tag | Any valid BCP 47 tag |
| Values Google accepts in hreflang sets | Not applicable | An ISO 639-1 language, optionally a region in ISO 3166-1 Alpha 2 or a script in ISO 15924, or `x-default` |
| Effect on Google's language detection | None, by Google's own statement | None, by the same statement |

## Valid values, and where they differ

Both attributes take BCP 47 tags, and the W3C's advice on choosing one is to keep the tag as short as the context allows. Add a region only when it distinguishes something your readers would notice, such as British spelling for a spell checker.

Google's hreflang support is narrower than BCP 47. Its documentation names `es-419`, Spanish for Latin America, as unsupported, since Google accepts only codes listed in ISO 639-1 and ISO 3166-1 Alpha 2. Our reading is that the numeric region `419` is what rules it out, as ISO 3166-1 Alpha 2 codes are two letters. The W3C uses the same `es-419` as a correct example of a BCP 47 region subtag. So `lang="es-419"` is a perfectly good declaration on a page, while the same page's hreflang entry needs `es`, or a two-letter region such as `es-MX`.

Case does not matter to either. By convention the region is written in capitals (`en-GB`) and a script subtag with a capital first letter (`zh-Hant`).

WordPress adds one wrinkle. Its locales use an underscore (`en_US`, `nl_NL`), which is not valid in a language tag. The function behind `language_attributes()` takes the language from `get_bloginfo('language')`, which returns a hyphenated tag: the one the WordPress translation supplies, or the locale with its underscore replaced. A theme that calls it prints `lang="en-US"` or `lang="nl-NL"`.

## Do lang and hreflang have to match?

They should agree on the language, though they need not be the same string. A WordPress page with `lang="en-US"` whose own hreflang entry is `en` is fine: both say English. A German translation that still carries `lang="en-US"` is the bug to look for.

That bug is common on multilingual WordPress sites for a structural reason. A translation plugin that serves `/de/` from the original post renders the page through the same theme, and the theme prints whatever `language_attributes()` returns for the site's language. Unless the plugin rewrites the attribute on the translated response, the German page goes out declaring itself English, and a screen reader reads German text with English pronunciation rules.

## Does Google use lang to detect a page's language?

No. Google's page on localized versions, last updated on 2026-09-21, says: "Google doesn't use hreflang or the HTML lang attribute to detect the language of a page; instead, we use algorithms to determine the language."

Set `lang` for the people and software reading the page. An accessibility audit flags a missing one whatever Google does with it.

## Both in one head

A pottery studio publishes in English and translates into Italian and Dutch. This is the start of the Italian version of its workshops page:

```
<!doctype html>
<html lang="it">
<head>
  <meta charset="utf-8">
  <title>Laboratori di ceramica | Linden Pottery</title>
  <link rel="canonical" href="https://www.lindenpottery.example/it/workshops/">
  <link rel="alternate" hreflang="en" href="https://www.lindenpottery.example/workshops/">
  <link rel="alternate" hreflang="it" href="https://www.lindenpottery.example/it/workshops/">
  <link rel="alternate" hreflang="nl" href="https://www.lindenpottery.example/nl/workshops/">
  <link rel="alternate" hreflang="x-default" href="https://www.lindenpottery.example/workshops/">
</head>
```

`lang="it"` tells the browser and assistive technology that this document is Italian. The four alternate lines tell a search engine where the English, Italian and Dutch versions live and which one to show everyone else. The `it` line and the `lang` value agree, which is what you check first on any translated page. For right-to-left text such as Arabic or Hebrew, the W3C also asks for the `dir` attribute.

## Both attributes on a language switcher

A language switcher is the one place where `hreflang` and `lang` belong on the same element. Each link leads to a page in another language, which is what `hreflang` on an `<a>` describes. Its text is usually that language's own name, "Italiano" or "Nederlands", which is text in another language than the page, so `lang` applies to it.

The W3C warns about one case. If the link also has a `title` attribute written in the current page's language, `lang` on the `<a>` would mislabel the title too. In that case, put `lang` on a `<span>` around the name instead.

LangRelay's [language switcher](https://www.langrelay.com/language-switcher) shows each language's own name by default and prints its links with no `title` attribute, so `lang` sits on the link itself. Stripped down to the attributes that matter here, a link looks like this:

```
<a href="https://www.lindenpottery.example/nl/workshops/" hreflang="nl" lang="nl"><span>Nederlands</span></a>
```

## How LangRelay sets both

In LangRelay, each language a site translates into is one BCP 47 tag, such as `de` or `nl`. The hreflang value and the `lang` value are both that tag, and the URL prefix is its lowercase form, so `/nl/` serves `lang="nl"` and is listed as `hreflang="nl"`. A formality choice, such as German Sie or du, changes the wording of the translation and never the tag.

On a translated page, LangRelay's WordPress plugin sets `lang` on the `<html>` element to the language's tag, replacing what the theme printed or adding the attribute if the theme printed none. The original page keeps the value WordPress gives it from the site language, so check that the site language in WordPress matches the language your content is written in.

After a release, LangRelay fetches the translated URL and compares its `lang` with the language it published, alongside the canonical and the page's own hreflang entry. If they disagree, the page is flagged on the release.

## How to check a live page

```
curl -s https://www.lindenpottery.example/it/workshops/ | grep -o '<html[^>]*>'
curl -s https://www.lindenpottery.example/it/workshops/ | grep -i 'hreflang'
```

The first line should show the page's language. The second should include an entry for that same language pointing at the URL you fetched. An accessibility checker such as axe reports a missing `lang` as `html-has-lang`.

The rest of the cluster covers the other entries in the head: [hreflang and canonical tags](https://www.langrelay.com/blog/hreflang-and-canonical-tags), [self-referencing hreflang and x-default](https://www.langrelay.com/blog/self-referencing-hreflang-x-default), [hreflang in XML sitemaps](https://www.langrelay.com/blog/hreflang-xml-sitemap) and [hreflang in WordPress](https://www.langrelay.com/blog/hreflang-wordpress). The [multilingual SEO](https://www.langrelay.com/multilingual-seo) page sums up what the plugin does for search, and you can [book a demo](https://www.langrelay.com/book-a-demo) to see it on your own site.

## Sources

The pages this one cites, with the day each was read.

1. 01[lang (MDN Web Docs, last modified 2026-09-08)](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/lang)developer.mozilla.org, checked 6 October 2026
2. 02[<link>: The External Resource Link element (MDN Web Docs, last modified 2026-05-20)](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/link)developer.mozilla.org, checked 6 October 2026
3. 03[HTML Living Standard, section 4.6 Links (WHATWG)](https://html.spec.whatwg.org/multipage/links.html)html.spec.whatwg.org, checked 6 October 2026
4. 04[Understanding Success Criterion 3.1.1: Language of Page (W3C WAI, WCAG 2.2)](https://www.w3.org/WAI/WCAG22/Understanding/language-of-page.html)w3.org, checked 6 October 2026
5. 05[Declaring language in HTML (W3C Internationalization)](https://www.w3.org/International/questions/qa-html-language-declarations)w3.org, checked 6 October 2026
6. 06[Choosing a language tag (W3C Internationalization)](https://www.w3.org/International/questions/qa-choosing-language-tags)w3.org, checked 6 October 2026
7. 07[Localized versions of your pages (Google Search Central, last updated 2026-09-21)](https://developers.google.com/search/docs/specialty/international/localized-versions)developers.google.com, checked 6 October 2026
8. 08[html-has-lang: <html> element must have a lang attribute (Deque University, axe 4.10)](https://dequeuniversity.com/rules/axe/4.10/html-has-lang)dequeuniversity.com, checked 6 October 2026
9. 09[get\_language\_attributes() (WordPress Developer Resources)](https://developer.wordpress.org/reference/functions/get_language_attributes/)developer.wordpress.org, checked 6 October 2026
10. 10[get\_bloginfo() (WordPress Developer Resources)](https://developer.wordpress.org/reference/functions/get_bloginfo/)developer.wordpress.org, checked 6 October 2026

[Chris Jayden](https://www.langrelay.com/about)

Founder, LangRelay

Chris Jayden is the founder of LangRelay. Chris has worked on websites of every size, from large e-commerce stores to small sites with a handful of pages, and started LangRelay after years of translating them the hard way.

On this page

1. What the lang attribute does
2. What hreflang does
3. The two side by side
4. Valid values, and where they differ
5. Do lang and hreflang have to match?
6. Does Google use lang to detect a page's language?
7. Both in one head
8. Both attributes on a language switcher
9. How LangRelay sets both
10. How to check a live page

Share

- [Share on LinkedIn (opens in a new tab)](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.langrelay.com%2Fblog%2Fhreflang-vs-html-lang)
- [Share on X (opens in a new tab)](https://x.com/intent/post?url=https%3A%2F%2Fwww.langrelay.com%2Fblog%2Fhreflang-vs-html-lang&amp;text=Hreflang%20vs%20the%20HTML%20lang%20attribute%3A%20what%20each%20one%20does)

See it on your site

A 30-minute walkthrough on one of your pages.

[Book a demo](https://www.langrelay.com/book-a-demo)

- accessibility
- hreflang
- lang attribute
- multilingual SEO

## Keep reading

- Article
  ### [Hreflang in XML sitemaps: syntax, limits and common errors](https://www.langrelay.com/blog/hreflang-xml-sitemap)
  When to put hreflang in a sitemap instead of the page head, one valid multilingual sitemap to copy, Google's size limits and the errors that break the file.
- Article
  ### [Hreflang in WordPress: how plugins print it and how to check](https://www.langrelay.com/blog/hreflang-wordpress)
  Where hreflang comes from on WordPress, what WPML, Polylang, TranslatePress and Weglot print by default, how Yoast SEO and Rank Math fit in, and how to check.
- Feature
  ### [Website Language Switcher You Design on Your Own Page](https://www.langrelay.com/language-switcher)
  Design a language switcher on a live preview of your page: floating or in-page placement, labels, flags, colors and mobile behavior, all from one designer.

Book a demo

## See LangRelay on your own site

Book 30 minutes with the team. We translate one of your pages live and walk through review, publishing and multilingual SEO.

[Book a demo](https://www.langrelay.com/book-a-demo)[See pricing](https://www.langrelay.com/pricing)
