Templates & Data
Translation strings can contain {{var}} placeholders. Pass values via data:
await ilingo.get({
namespace: 'app',
key: 'age',
data: { age: 18 },
});
// "I am 18 years old"Missing-data semantics
A {{var}} whose key is not in data is left untouched — the placeholder stays in the output. This is intentional: missing data is a developer-facing signal, not an error.
import { Ilingo, MemoryStore, defineCatalog, defineLocale, defineNamespace, defineTranslations } from 'ilingo';
const store = new MemoryStore({
data: defineCatalog([
defineLocale('en', [defineNamespace('app', [defineTranslations({ hi: 'Hello, {{name}}!' })])]),
]),
});
const ilingo = new Ilingo({ store });
await ilingo.get({ namespace: 'app', key: 'hi' });
// "Hello, {{name}}!"Catch these in development with the missing-key handler or with a linter.
Count is auto-merged
When count is passed to get(), it is automatically copied into data if not already present:
await ilingo.get({
namespace: 'cart',
key: 'items',
count: 5,
});
// data is effectively { count: 5 }This means {{count}} works in plural forms without restating it. Explicitly setting data.count overrides the auto-merge.
Nested keys
Keys are dotted paths into the namespace's object:
const store = new MemoryStore({
data: defineCatalog([
defineLocale('en', [
defineNamespace('settings', [
defineTranslations({
profile: {
avatar: 'Change avatar',
nested: { deep: 'Deep value' },
},
}),
]),
]),
]),
});
await ilingo.get({ namespace: 'settings', key: 'profile.avatar' });
// "Change avatar"
await ilingo.get({ namespace: 'settings', key: 'profile.nested.deep' });
// "Deep value"Path resolution is provided by pathtrace — same dot-notation semantics as lodash.get.
Modifiers (formatters)
Placeholders also accept inline modifiers — see Formatters.
'You owe {{amount, number(style=currency, currency=EUR)}}'Slot placeholders
Beyond {{var}} (double curly braces, substituted from data), messages can carry {slot} placeholders (single curly braces) that are filled by named scoped slots in renderer-aware components. The plain template() function leaves {slot} markers as literal text — only slot-aware renderers like <ITranslateT> consume them.
'Hi {{user}}, please {cta} to continue.'
// ^^^^^^ ^^^^^
// data var slotUse cases: dropping a <a> tag, icon, or bold run into the middle of a translated sentence without splitting the message across keys.
See Vue integration for the consumer-side syntax.
tokenize() — for renderers
For renderers that produce non-string output (VNodes, JSX, etc.), the core exposes a tokenize(str): TemplateToken[] helper that parses a message into text / var / slot tokens. This is what <ITranslateT> uses internally; the same primitive lets any future framework adapter walk the same AST.
import { tokenize } from 'ilingo';
tokenize('Hi {{user}}, please {cta} now.');
// [
// { kind: 'text', value: 'Hi ' },
// { kind: 'var', name: 'user' },
// { kind: 'text', value: ', please ' },
// { kind: 'slot', name: 'cta' },
// { kind: 'text', value: ' now.' },
// ]tokenize and template are parallel parsers over the same syntax — template returns a substituted string for Ilingo.format's common case; tokenize returns tokens for structured renderers.