Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
How Vanilla Breeze handles script-specific typography, ruby visibility, locale-aware quotes, translate conventions, and locale resolution.
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.
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>
| Script | Languages | Token | Line Height |
|---|---|---|---|
| CJK | zh, ja, ko | --font-cjk | 1.8 |
| Arabic | ar, fa, ur, ps | --font-arabic | 1.9 |
| Hebrew | he, yi | --font-hebrew | 1.75 |
| Thai | th | --font-thai | 2.0 |
| Devanagari | hi, mr, sa, ne | --font-devanagari | 1.75 |
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;}
Control ruby annotation display with data-ruby on <html>:
| Value | Behavior |
|---|---|
show | Always visible |
hide | Visually hidden, kept in DOM for accessibility |
auto | Visible 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>
The <q> element renders locale-appropriate quotation marks via CSS quotes:
| Language | Outer | Inner |
|---|---|---|
| English (US) | “...” | ‘...’ |
| English (GB, AU, NZ) | ‘...’ | “...” |
| German | „...“ | ‚...‘ |
| French | « ... » | ‹ ... › |
| Italian / Spanish / Portuguese | «...» | “...” |
| Polish | «...» | „...“ |
| Japanese / Chinese | 「...」 | 『...』 |
| Korean | “...” | ‘...’ |
| Russian | «...» | „...“ |
| Arabic | «...» | ‘...’ |
<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>
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>
VB provides a centralized getLocale() function that all format utilities share. The priority chain:
<html lang> attributenavigator.language'en' fallbackIndividual 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>
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'); // trueusesRuby('ja'); // trueprimarySubtag('zh-TW'); // 'zh'/code-block <h2>VbI18n String Swap</h2><p>For application-level translation, VB exports a <code>VbI18n</code> class. It is <strong>not</strong> auto-initialized — you instantiate and configure it with your own message maps.</p> <code-block language="js" label="VbI18n setup" data-escape>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] elementsi18n.apply(); // Listen for locale changesi18n.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>
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; }
i18n Typography Demo — live examples of all features on this page.
<ruby> — Container for ruby annotations (furigana, pinyin)<rt> — Ruby text (the annotation content)<rp> — Fallback parentheses for non-supporting browsers<bdi> — Bidirectional isolate (safe for user-generated content with unknown direction)<bdo> — Bidirectional override (force a specific text direction)