Internationalization

How Vanilla Breeze handles script-specific typography, ruby visibility, locale-aware quotes, translate conventions, and locale resolution.

Philosophy

Internationalization is not a feature you add — it is a constraint you respect from the start. VB treats i18n the same way it treats semantic HTML: build it in, don't bolt it on.

The web platform already has most of what you need: the lang attribute, CSS :lang(), logical properties, the Intl API, the translate attribute, and ruby HTML elements. VB uses them correctly and consistently.

Script-Specific Typography

Set lang on any element and VB automatically applies the right font family, line height, letter spacing, and word-breaking rules. This works via CSS :lang() which inherits through the subtree.

<html lang="ja"> <!-- CJK font, line-height: 1.8, word-break: break-all --> </html> <section lang="ar" dir="rtl"> <!-- Arabic font, line-height: 1.9, RTL layout --> </section>

Supported Scripts

ScriptLanguagesTokenLine Height
CJKzh, ja, ko--font-cjk1.8
Arabicar, fa, ur, ps--font-arabic1.9
Hebrewhe, yi--font-hebrew1.75
Thaith--font-thai2.0
Devanagarihi, mr, sa, ne--font-devanagari1.75

Font Token Slots

VB provides custom properties for each script family. Override them to load your preferred fonts:

:root { --font-cjk: "Noto Sans CJK SC", "PingFang SC", system-ui, sans-serif; --font-arabic: "Noto Sans Arabic", "Segoe UI", system-ui, sans-serif; --font-hebrew: "Noto Sans Hebrew", "Segoe UI", system-ui, sans-serif; --font-thai: "Noto Sans Thai", "Leelawadee UI", system-ui, sans-serif; --font-devanagari: "Noto Sans Devanagari", system-ui, sans-serif; }

Ruby Visibility

Control ruby annotation display with data-ruby on <html>:

ValueBehavior
showAlways visible
hideVisually hidden, kept in DOM for accessibility
autoVisible for CJK languages, hidden otherwise
(absent)Browser default
<html lang="ja" data-ruby="auto"> <body> <!-- Ruby visible because lang="ja" --> <ruby>漢<rt>かん</rt></ruby><ruby>字<rt>じ</rt></ruby> <!-- English section: ruby hidden in auto mode --> <section lang="en"> <ruby>ruby<rt>annotation</rt></ruby> </section> </body> </html>

Locale-Aware Quotes

The <q> element renders locale-appropriate quotation marks via CSS quotes:

LanguageOuterInner
English“...”‘...’
German„...“‚...‘
French«...»‹...›
Japanese / Chinese「...」『...』
Russian«...»„...“
<p lang="de">Sie sagte <q>hallo</q>.</p> <p lang="fr">Elle a dit <q>bonjour</q>.</p> <p lang="ja">彼女は<q>こんにちは</q>と言いました。</p>

Translate Conventions

VB automatically sets translate: no on elements that should never be machine-translated: <code>, <kbd>, <samp>, <pre>, and <var>.

For your own content, use the HTML translate attribute on brand names, identifiers, and technical terms:

<p>Install <span translate="no">Vanilla Breeze</span> via npm.</p> <p>Your username is <span translate="no">tpowell42</span>.</p>

Locale Resolution (JS)

VB provides a centralized getLocale() function that all format utilities share. The priority chain:

  1. <html lang> attribute
  2. navigator.language
  3. 'en' fallback

Individual elements can override via data-locale:

<html lang="de"> <!-- All format utilities use German locale by default --> <data value="1234.56" data-format-number>1.234,56</data> <!-- Override for this specific element --> <data value="1234.56" data-format-number data-locale="en-US">1,234.56</data> </html>

JS Utilities

Import locale utilities for custom components:

import { getLocale, isRTL, usesRuby, primarySubtag } from './lib/i18n.js'; getLocale(); // 'en-US' (from html[lang] or navigator) isRTL('ar'); // true usesRuby('ja'); // true primarySubtag('zh-TW'); // 'zh'

VbI18n String Swap

For application-level translation, VB exports a VbI18n class. It is not auto-initialized — you instantiate and configure it with your own message maps.

import { VbI18n } from './lib/i18n.js'; const i18n = new VbI18n({ locale: 'fr', messages: { en: { 'nav.home': 'Home', 'actions.close': 'Close' }, fr: { 'nav.home': 'Accueil', 'actions.close': 'Fermer' }, } }); // Swap all [data-i18n] elements i18n.apply(); // Listen for locale changes i18n.watch(); <nav> <a href="/" data-i18n="nav.home">Home</a> </nav> <button data-i18n="actions.close">Close</button> <!-- Attribute targeting --> <input data-i18n="form.search" data-i18n-attr="placeholder" placeholder="Search..."> <!-- Variable interpolation --> <p data-i18n="welcome" data-i18n-vars='{"name":"World"}'>Hello, World!</p>

Logical Properties

VB uses CSS logical properties throughout (465+ instances). RTL layout works automatically when you set dir="rtl" on <html>. No additional CSS is needed.

/* VB never writes this: */ .card { padding-left: 1rem; margin-right: auto; } /* VB always writes this: */ .card { padding-inline-start: 1rem; margin-inline-end: auto; }

Demo

i18n Typography Demo — live examples of all features on this page.

Related