Get started

Use this page to get a working localized UI quickly. Start with a runtime scope, then add tags and helper calls as you expand the page.

Step 1 — Initialize a locale scope

html
1<intl-locale locale="en-US" fallback-locale="en" src-dir="/locales" update-document>2    <header>3        <intl-msg key="header.title">Product</intl-msg>4        <intl-number type="currency" currency="USD">1299.99</intl-number>5    </header>6</intl-locale>

This creates one locale runtime boundary and loads translation files from /locales/en-US.json.

Step 2 — Render translated text

html
1<intl-msg key="product.name">Default product name</intl-msg>

<intl-msg> first renders its tag content, then replaces it when message lookup is available.

Step 3 — Add rich formatting

html
1<intl-datetime date-style="long">2026-01-01T10:00:00Z</intl-datetime>2<intl-list type="conjunction">shipping tax discounts</intl-list>3<intl-rel-time live>2026-01-01T00:00:00Z</intl-rel-time>

Step 4 — Run from code when you need runtime logic

ts
1import { initIntl, intlPlural, createIntl } from '@beforesemicolon/intl'2 3const runtime = initIntl({4    locale: 'en-US',5    fallbackLocale: 'en',6    messages: {7        inbox: {8            title: '{value} messages',9        },10    },11})12 13runtime.getMessage('inbox.title') // direct message read14intlPlural(3, {15    type: 'cardinal',16    one: 'item',17    other: 'items',18    locale: 'en-US',19})

Step 5 — Use nested scopes for sections

html
1<intl-locale locale="en-US">2    <intl-msg key="global.cta">Get started</intl-msg>3 4    <intl-locale locale="fr-FR">5        <intl-msg key="global.cta">Commencer</intl-msg>6    </intl-locale>7</intl-locale>

Next step

If this works, move on to:

edit this doc