Skip to main content

Located at

The Localizer is used for two things: text translation and locale-aware formatting of numbers, dates and relative time.

Quick start

If you want to make localization as easy as possible, just:

  1. set lang to <html>,
  2. create window.translations = new Map(),
  3. register the translation via Localizer.registerTranslation(...),
  4. create new Localizer(...),
  5. call translate(), translateWithParams(), translatePlural(), formatNumber(), formatDate(), and relativeTime().

index.html

<!doctype html>
<html lang="sk-sk">
<head>
<script>
window.translations = new Map();
</script>
<script type="module" src="/src/main.js"></script>
</head>
<body></body>
</html>

main.js

import 'wj-elements';
import { Localizer } from 'wj-elements';

Localizer.registerTranslation({
code: 'en-sk',
name: 'Slovak',
dir: 'ltr',
'app.hello': 'Hi',
'app.greeting': 'Hi {name}',
'cart.items.one': '{count} item',
'cart.items.few': '{count} items',
'cart.items.other': '{count} items',
});

const localizer = new Localizer(document.documentElement);

console.log(localizer.translate('app.hello'));
console.log(localizer.translateWithParams('app.greeting', { name: 'Ján' }));

const template = localizer.translatePlural('cart.items', 3);
console.log(template.replace('{count}', 3));

console.log(localizer.formatNumber(1234.56, {
style: 'currency',
currency: 'EUR',
}));

console.log(localizer.formatDate(new Date(), { dateStyle: 'long' }));
console.log(localizer.relativeTime(undefined, -1, 'day'));

In this example, the language is taken from <html lang="sk-sk">, the translations are registered when the application starts, and the localizer is then used anywhere in the code.

Language

Localizer searches for language in the following order:

  1. element.lang
  2. document.documentElement.lang
  3. internal default en-GB
important

In practice, do not rely on the default. Always set lang explicitly and use lowercase language codes such as en-eng and en-gb. Registered translations are stored lowercase, and the current implementation expects the same form.

Component

The most common pattern in the web component is:

import { Localizer, WJElement } from 'wj-elements';

export default class AppGreeting extends WJElement {
constructor() {
super();
this.localizer = new Localizer(this);
}

draw() {
const div = document.createElement('div');
div.textContent = this.localizer.translateWithParams('app.greeting', {
name: 'Ján',
});

return div;
}
}

Outside of the component, new Localizer(document.body) or new Localizer(document.documentElement) is typically used.

Setup

new Localizer()

Creates a new instance of the localizer.

ParameterTypeDescription
elementHTMLElement | Element | object with optional lang and dirThe element from which lang and dir are read.

Most common use:

const appLocalizer = new Localizer(document.documentElement);
const serviceLocalizer = new Localizer(document.body);
const componentLocalizer = new Localizer(this);

registerTranslation()

Registers one or more translation objects.

ParameterTypeDescription
...translationobject[]One or more objects with the code field.

A translation object is an ordinary object:

FieldTypeRequiredDescription
codestringYesA language code, for example en-eng, en-gb, de-de-de.
namestringNoLegible name of the language.
dirstringNoThe direction of the text, usually ltr or rtl.
other fieldsstringNoTranslation keys and their values.

Example:

window.translations = new Map();

Localizer.registerTranslation(
{
code: 'en-sk',
name: 'Slovak',
'global.save': 'Save',
},
{
code: 'en-gb',
name: 'English',
'global.save': 'Save',
}
);

Behavior:

  • The window.translations must exist before the first call,
  • if you register the same language multiple times, the keys will be merged,
  • if the new object contains an existing key, overwrites it,
  • if the object does not have a code, an error is printed to the console.

localizer.setLanguage()

Re-evaluates the active language according to localizer.lang.

Use it after you change the lang while the application is running.

document.documentElement.lang = 'en-gb';
localizer.lang = 'en-gb';
localizer.setLanguage();

convertLangCode()

Converts frontend language code to a form that is often used in API data.

localizer.convertLangCode('en-sk');
// en_SK

Practical example:

const apiKey = localizer.convertLangCode(localizer.currentLang);
const label = item.name?.values?.[apiKey];

Translations

translate()

Returns the translation for the given key.

ParameterTypeDescription
keystringTranslation key.

If the key does not exist, the original key is returned.

localizer.translate('app.hello');
// 'hello'

translateWithParams()

Translates the text and adds placeholders in the format {name}.

ParameterTypeDefault valueDescription
keystring-Translation key.
paramsRecord<string, unknown>{}Values for placeholders.

Behavior:

  • placeholder is replaced if the value exists,
  • the value is converted to a string,
  • if the value is missing or null, the placeholder remains unchanged.
localizer.translateWithParams('app.greeting', {
name: 'Jan',
});
// 'Hi Jan'

translatePlural()

Selects the correct pluralization form via Intl.PluralRules.

ParameterTypeDefault valuePossible valuesDescription
keystring--Basic key without suffix.
countnumber0any numberThe number by which the shape is selected.
typestring'cardinal''cardinal', 'ordinal'Type of pluralization.

The method looks for keys in the shape:

  • <key>.zero
  • <key>.one
  • <key>.two
  • <key>.few
  • <key>.many
  • <key>.other

If the exact shape does not exist, it uses the fallback <key>.other.

const template = localizer.translatePlural('cart.items', 3);
const text = template.replace('{count}', 3);
// '3 items'
note

translatePlural() just selects the correct string. If you have placeholders such as {count} in the text, fill them in yourself.

Formatting

formatNumber()

The function for numbers is called formatNumber() in the API. There is no separate translateNumber().

Formats the number via Intl.NumberFormat.

ParameterTypeDescription
numbernumberNumber for formatting.
optionsIntl.NumberFormatOptionsFormatting options.

The most common choices:

OptionPossible values
style'decimal', 'currency', 'percent', 'unit'
currencyfor example 'EUR', 'USD'
currencyDisplay'code', 'symbol', 'narrowSymbol', 'name'
currencySign'standard', 'accounting'
unitfor example 'byte', 'kilobyte', 'meter', 'celsius'
unitDisplay'short', 'long', 'narrow'
notation'standard', 'scientific', 'engineering', 'compact'
compactDisplay'short', 'long'
signDisplay'auto', 'never', 'always', 'exceptZero', 'negative'
useGroupingtrue, false, 'auto', 'always', 'min2'
minimumIntegerDigitsnumber
minimumFractionDigitsnumber
maximumFractionDigitsnumber
minimumSignificantDigitsnumber
maximumSignificantDigitsnumber
roundingPriority'auto', 'morePrecision', 'lessPrecision'
roundingIncrement1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000
roundingMode'ceil', 'floor', 'expand', 'trunc', 'halfCeil', 'halfFloor', 'halfExpand', 'halfTrunc', 'halfEven'
trailingZeroDisplay'auto', 'stripIfInteger'

Examples:

localizer.formatNumber(1234.56, {
style: 'currency',
currency: 'EUR',
});

localizer.formatNumber(2048, {
style: 'unit',
unit: 'kilobyte',
unitDisplay: 'short',
});

formatDate()

Formats the date via Intl.DateTimeFormat.

ParameterTypeDescription
date`string \Date \
optionsIntl.DateTimeFormatOptionsFormatting options.

The most common choices:

OptionPossible values
dateStyle'full', 'long', 'medium', 'short'
timeStyle'full', 'long', 'medium', 'short'
weekday'long', 'short', 'narrow'
era'long', 'short', 'narrow'
year'numeric', '2-digit'
month'numeric', '2-digit', 'long', 'short', 'narrow'
day'numeric', '2-digit'
dayPeriod'narrow', 'short', 'long'
hour'numeric', '2-digit'
minute'numeric', '2-digit'
second'numeric', '2-digit'
fractionalSecondDigits1, 2, 3
hour12true, false
hourCycle'h11', 'h12', 'h23', 'h24'
timeZonefor example 'Europe/Bratislava', 'UTC'
timeZoneName'short', 'long', 'shortOffset', 'longOffset', 'shortGeneric', 'longGeneric'
calendarfor example 'gregory'
numberingSystemFor example, 'latn', 'arab'
localeMatcherlookup, best fit
formatMatcher'basic', 'best fit'

Examples:

localizer.formatDate(new Date(), {
dateStyle: 'long',
});

localizer.formatDate('2026-03-29T15:45:00Z', {
dateStyle: 'short',
timeStyle: 'short',
timeZone: 'Europe/Bratislava',
});

relativeTime()

Formats the relative time via Intl.RelativeTimeFormat.

ParameterTypeDefault valuePossible valuesDescription
langstringthis.currentLanglocale code or undefinedOutput language.
valuenumber0negative and positive numbersA shift in time.
unitstring'day''year', 'years', 'quarter', 'quarters', 'month', 'months', 'weeks', 'weeks', 'day', 'days', 'hour', 'hours', 'minutes', 'minutes', 'seconds'Unit of time.
optionsIntl.RelativeTimeFormatOptions{ numeric: 'auto' }see belowFormatting options.

Options options:

OptionPossible values
numeric'always', 'auto'
style'long', 'short', 'narrow'
localeMatcherlookup, best fit

Examples:

localizer.relativeTime(undefined, -1, 'day');
// for example 'yesterday'

localizer.relativeTime('en-gb', 3, 'week', {
numeric: 'always',
style: 'short',
});
// 'in 3 wk.
note

The first parameter is lang. To use the current language of the localizer, send undefined, null or an empty string.