Internationalisation (often shortened to i18n) is about making pages work for different languages, writing directions, and regional conventions. HTML gives you a small set of attributes that help browsers, assistive tech, and search engines treat the page correctly – and this tutorial sticks to those basics.
You already know document structure. Here we focus on lang, dir, and how to mark up dates and numbers so machines and humans both get a fair chance.
lang on the root element
Every page should declare its primary language on <html>:
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<title>Contact us</title>
</head>
<body>
<!-- ... -->
</body>
</html>
Use a valid BCP 47 language tag. Common examples: en-GB (British English), en-US, cy (Welsh), fr, de. The tag drives screen reader pronunciation, hyphenation, and font selection hints.
Wrong or missing lang means a screen reader might read English text with French pronunciation rules. Fix this on every template.
lang on inline content
When a phrase or block uses a different language from the page default, mark it:
<p lang="en-GB">
The French motto
<span lang="fr">liberté, égalité, fraternité</span>
appears on public buildings.
</p>
Apply lang to the smallest element that wraps the foreign text – a <span>, <q>, or <blockquote>. Block quotes in another language often sit on <blockquote lang="..."> with a cite attribute if you have a source URL.
When not to translate
Product names, code identifiers, and brand strings sometimes should stay as-is:
<p>
Install <span translate="no">Homebrew</span> before continuing.
</p>
translate="no" hints to automatic translation tools that the span should be left alone. Use sparingly; do not slap it on whole paragraphs because you could not be bothered to send strings to a translator.
dir for text direction
Languages written right-to-left (Arabic, Hebrew, and others) need dir="rtl" on <html> or on the relevant section:
<html lang="ar" dir="rtl">
<!-- page content -->
</html>
Mixed-direction pages (English UI with Arabic quotes) might use:
<p dir="ltr" lang="en-GB">Customer reference: <strong>GB-1042</strong></p>
<blockquote dir="rtl" lang="ar">
<p>...</p>
</blockquote>
Direction affects layout as well as text flow. CSS logical properties (margin-inline-start instead of hard-coded margin-left) pair well with RTL sites. That is mostly CSS, but your HTML should declare direction honestly so the browser does not guess.
Dates and times
Humans read friendly dates; machines prefer ISO 8601. The <time> element covers both:
<p>
Published
<time datetime="2026-07-28">28 July 2026</time>.
</p>
<p>
Doors open at
<time datetime="2026-07-28T19:30+01:00">7:30 pm</time>.
</p>
Display text can follow local convention (day/month order for UK readers). The datetime attribute stays unambiguous. Include timezone offset when times matter internationally.
Numbers and currency
HTML has no special tag for currency. You mark up the value clearly and let CSS or locale-aware JavaScript handle formatting if needed:
<p>
Call-out fee:
<data value="120.00">£120.00</data>
</p>
The <data> element ties a machine-readable value to visible text. For simple static sites, writing £1,234.56 in British English pages and $1,234.56 on US pages is often enough. For dynamic apps, format numbers in PHP or JavaScript using locale APIs (Intl.NumberFormat in JS, NumberFormatter in PHP) rather than concatenating strings by hand.
hreflang (linked pages)
When you publish the same content in multiple languages on separate URLs, <link rel="alternate" hreflang="..."> in the head helps search engines connect the versions:
<link rel="alternate" hreflang="en-GB" href="https://example.com/contact/">
<link rel="alternate" hreflang="fr" href="https://example.com/fr/contact/">
<link rel="alternate" hreflang="x-default" href="https://example.com/contact/">
That is head markup rather than body content, but it belongs in the same i18n conversation. Each language version should still set its own lang on <html>.
Practical checklist
<html lang="...">set on every page.dir="rtl"when the primary language needs it.- Inline
langon foreign phrases and quotes. <time datetime>for dates that matter to machines or calendars.- Consistent number and currency formatting per locale.
hreflanglinks if you maintain parallel language URLs.
Good i18n starts in HTML with honest language and direction declarations. Translation workflows and locale libraries build on that foundation; they do not replace it.

