ESC

Type to search the knowledge base.

lang Attribute and i18n HTML

Set lang and dir for language and direction — nested language spans, hreflang, and what HTML owns vs your i18n framework.

beginner3 min read
  • html
  • lang
  • i18n

The lang attribute declares the human language of content. Assistive tech uses it for pronunciation and voice selection, browsers for hyphenation and fonts, and search engines as a language signal. dir declares base direction for bidirectional text.

Docs: MDN lang, dir, W3C language tags.

Document language

<!DOCTYPE html>
<html lang="en">
<html lang="fr-CA">

Use BCP 47 tags: primary language (en, fr, zh) plus optional region (en-GB, pt-BR) and variants. Be accurate — en for mostly English UI is fine; don’t mark French pages as en.

Nested language changes

<p>
  The French phrase
  <span lang="fr">c’est la vie</span>
  is common in English prose.
</p>

Mark genuine language switches so screen readers switch pronunciation. Don’t mark brand names that are pronounced as English.

Direction

<html lang="ar" dir="rtl">
<p dir="rtl" lang="ar">…</p>
<p>Invoice total: <span dir="ltr">$42.00</span></p>
  • dir="rtl" | ltr | auto
  • Prefer logical CSS (margin-inline-start) so layouts flip with direction

dir="auto" estimates from first strong character — useful for user-generated content of unknown language.

SPA locale switches

When the user changes language:

document.documentElement.lang = "es";
document.documentElement.dir = "ltr";
document.title = t("app.title");

Update lang/dir on <html>, not only in-memory i18n state. Translate title and critical aria-labels too.

hreflang for multilingual sites

<link rel="alternate" hreflang="en" href="https://example.com/en/pricing" />
<link rel="alternate" hreflang="de" href="https://example.com/de/pricing" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />

Helps search engines serve the right language URL. Keep reciprocal annotations consistent across pages.

What HTML won’t do for you

  • String catalogs and plural rules — i18n libraries
  • Locale-aware dates/numbers — Intl APIs
  • Translated images/alt — content process
  • Legal compliance for language of contract — product/legal

HTML declares language; your pipeline supplies translations.

Interview out-loud

“I set lang on html to the page language and use nested lang for true language switches. RTL languages get dir=rtl and logical CSS. SPAs must update documentElement.lang when locale changes. Multilingual SEO uses hreflang alternate links.”

Footguns

  1. Missing lang entirely.
  2. Wrong lang after client-side locale switch.
  3. Marking every italicized word as a foreign language.
  4. Physical CSS (margin-left) breaking RTL.
  5. Machine-translated lang tags that don’t match body text.

Mixed-direction product UI

<html lang="en">
…
<aside lang="ar" dir="rtl" class="preview-pane">
  <!-- user-generated Arabic content preview -->
</aside>

Isolate user content language when known. For chat apps, set lang/dir per message bubble based on detected or user-selected language. Pair with logical CSS so padding does not look wrong in either direction.

Screen reader pronunciation

Incorrect lang causes mispronunciation that can make content unintelligible. If your UI is English with a Japanese product name used as English branding, you usually leave it in the English lang context. If you embed a full Japanese paragraph, wrap it with lang="ja". Spot-check with VoiceOver/NVDA when shipping a new locale.

SEO language clusters

Serve each language at a stable URL (/en/…, /fr/… or ccTLDs). Annotate with hreflang bidirectionally. The html lang of each response must match the content language of that URL. Mismatches (English body with lang=fr) hurt both AT and quality signals. When auto-detecting language for a landing redirect, still let users switch and remember the choice.

Further reading

Related guides