Advanced15 min read

Internationalization

Learn how to build multilingual HTML pages using the lang attribute, text direction, ruby annotations, and other internationalization features.

The lang Attribute

The lang attribute declares the language of an element's content. It is one of the most important accessibility and internationalisation attributes in HTML.

On the root element

html
<html lang="en">

This tells browsers, screen readers, and search engines that the page content is in English. Screen readers use it to select the correct pronunciation rules. Search engines use it for indexing.

On specific sections

When a page contains content in multiple languages, set lang on the relevant elements:

html
<p>The French word for hello is <span lang="fr">bonjour</span>.</p>

Common language codes: en, fr, de, es, ja, zh, ar, ko, pt, ru. You can add region subtags: en-US, en-GB, fr-CA, zh-TW.

Text Direction: dir, <bdi>, <bdo>

Some languages are written right-to-left (RTL), including Arabic, Hebrew, Persian, and Urdu.

The dir attribute

  • dir="ltr" — Left-to-right (default for most languages).
  • dir="rtl" — Right-to-left.
  • dir="auto" — Let the browser detect direction from the content.
html
<html lang="ar" dir="rtl">

<bdi> — Bidirectional Isolate

Isolates a span of text that might be in a different direction from its surroundings, preventing it from affecting adjacent text:

html
<p>User: <bdi>محمد</bdi> posted 3 comments.</p>

Without <bdi>, the Arabic text could mess up the surrounding punctuation and numbers.

<bdo> — Bidirectional Override

Forces a specific text direction, overriding the Unicode bidirectional algorithm:

html
<bdo dir="rtl">Hello</bdo>  <!-- Renders as: olleH -->

Use <bdo> sparingly — it overrides the natural direction and can make text unreadable.

Ruby Annotations

Ruby annotations provide pronunciation guides above (or beside) characters, commonly used in East Asian typography:

  • Japanese furigana — reading aids above kanji characters.
  • Chinese pinyin — romanised pronunciation above Chinese characters.
html
<ruby>
  漢 <rp>(</rp><rt>kan</rt><rp>)</rp>
  字 <rp>(</rp><rt>ji</rt><rp>)</rp>
</ruby>

Elements:

  • <ruby> — Container for the annotated text.
  • <rt> — The annotation (pronunciation guide).
  • <rp> — Fallback parentheses shown in browsers that do not support ruby. Hidden when ruby is supported.

Result: The characters 漢字 are displayed with "kan" and "ji" as small text above them.

Other i18n Features

The hreflang attribute

On links, hreflang indicates the language of the linked document:

html
<a href="/fr/about" hreflang="fr">Version française</a>

Search engines use this to serve the correct language version to users.

The translate attribute

Controls whether content should be translated by automatic translation tools:

html
<p translate="no">Kodojo</p>  <!-- Brand name: do not translate -->
<code translate="no">console.log('hello')</code>  <!-- Code: do not translate -->

Language negotiation with <link>

For alternate language versions of the same page:

html
<link rel="alternate" hreflang="fr" href="https://example.com/fr/page">
<link rel="alternate" hreflang="en" href="https://example.com/en/page">
<link rel="alternate" hreflang="x-default" href="https://example.com/page">

Multilingual Page Example

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>i18n Demo</title>
</head>
<body>
  <h1>Internationalization in HTML</h1>

  <!-- French section -->
  <section lang="fr">
    <h2>Section en français</h2>
    <p>Bienvenue sur notre site.</p>
  </section>

  <!-- Arabic section (RTL) -->
  <section lang="ar" dir="rtl">
    <h2>مرحبا</h2>
    <p>أهلا وسهلا بكم.</p>
  </section>

  <!-- Japanese with ruby annotations -->
  <section lang="ja">
    <h2>
      <ruby>
        日 <rp>(</rp><rt>に</rt><rp>)</rp>
        本 <rp>(</rp><rt>ほん</rt><rp>)</rp>
        語 <rp>(</rp><rt>ご</rt><rp>)</rp>
      </ruby>
    </h2>
  </section>

  <!-- Brand name: do not translate -->
  <p>Powered by <span translate="no">Kodojo</span></p>

  <!-- Link to French version -->
  <a href="/fr/" hreflang="fr">Version française</a>
</body>
</html>

What is the purpose of the <bdi> element?

Ready to practice?

Create your free account to access the interactive code editor, run challenges, and track your progress.