Using Interpolation
This guide shows you how to insert dynamic values into your translations. You'll learn to use placeholders, handle different value types, and avoid common pitfalls.
Prerequisites
Before starting, you should:
Overview
We'll add dynamic values to translations by:
- Adding placeholders to translation strings
- Passing values when calling
t() - Handling edge cases like missing or null values
Step 1: Add Placeholders to Translations
Define your translations with {{placeholder}} syntax. Choose descriptive names:
import { createI18n } from '@motioneffector/i18n'
const i18n = createI18n({
defaultLocale: 'en',
translations: {
en: {
welcome: 'Welcome, {{username}}!',
balance: 'Your balance is {{amount}}',
status: '{{user}} is currently {{status}}'
}
}
})
Placeholders can appear anywhere in the string and can include spaces inside the braces ({{ username }} works too).
Step 2: Pass Values When Translating
Call t() with a second argument containing your values:
// Single placeholder
i18n.t('welcome', { username: 'Alice' })
// "Welcome, Alice!"
// Multiple placeholders
i18n.t('status', { user: 'Bob', status: 'online' })
// "Bob is currently online"
// Numeric values
i18n.t('balance', { amount: 150.00 })
// "Your balance is 150"
The keys in your params object must match the placeholder names exactly (case-sensitive).
Step 3: Handle Edge Cases
Understand how different values behave:
const i18n = createI18n({
defaultLocale: 'en',
translations: {
en: {
info: 'Value: {{value}}'
}
}
})
// String - used as-is
i18n.t('info', { value: 'hello' }) // "Value: hello"
// Number - converted to string
i18n.t('info', { value: 42 }) // "Value: 42"
i18n.t('info', { value: 3.14159 }) // "Value: 3.14159"
// Boolean - becomes "true" or "false"
i18n.t('info', { value: true }) // "Value: true"
// Null/undefined - becomes empty string
i18n.t('info', { value: null }) // "Value: "
i18n.t('info', { value: undefined }) // "Value: "
// Missing param - placeholder stays visible
i18n.t('info', {}) // "Value: {{value}}"
i18n.t('info') // "Value: {{value}}"
Complete Example
import { createI18n } from '@motioneffector/i18n'
const i18n = createI18n({
defaultLocale: 'en',
translations: {
en: {
greeting: 'Hello, {{name}}!',
order: {
summary: '{{customer}} ordered {{quantity}} x {{product}}',
total: 'Total: {{currency}}{{amount}}',
status: 'Order #{{orderId}} is {{status}}'
}
}
}
})
// Simple greeting
console.log(i18n.t('greeting', { name: 'World' }))
// "Hello, World!"
// Order information
console.log(i18n.t('order.summary', {
customer: 'Alice',
quantity: 3,
product: 'Widget'
}))
// "Alice ordered 3 x Widget"
console.log(i18n.t('order.total', {
currency: '%%CONTENT%%#39;,
amount: 29.97
}))
// "Total: $29.97"
console.log(i18n.t('order.status', {
orderId: 12345,
status: 'shipped'
}))
// "Order #12345 is shipped"
Variations
Reusing the Same Placeholder
A placeholder can appear multiple times in one string:
const i18n = createI18n({
defaultLocale: 'en',
translations: {
en: {
palindrome: '{{word}} spelled backwards is {{word}}'
}
}
})
i18n.t('palindrome', { word: 'level' })
// "level spelled backwards is level"
Combining with Namespaces
Use interpolation with namespaced translate functions:
const i18n = createI18n({
defaultLocale: 'en',
translations: {
en: {
errors: {
notFound: '{{resource}} not found',
unauthorized: '{{user}} lacks permission for {{action}}'
}
}
}
})
const tErrors = i18n.t.namespace('errors')
tErrors('notFound', { resource: 'User' })
// "User not found"
tErrors('unauthorized', { user: 'Guest', action: 'delete' })
// "Guest lacks permission for delete"
Troubleshooting
Placeholder Not Being Replaced
Symptom: You see {{name}} in the output instead of the value.
Cause: The param name doesn't match the placeholder exactly, or you forgot to pass params.
Solution: Check for typos and case sensitivity. {{Name}} and {{name}} are different.
// Wrong - case mismatch
i18n.t('greeting', { Name: 'Alice' }) // "Hello, {{name}}!"
// Right
i18n.t('greeting', { name: 'Alice' }) // "Hello, Alice!"
TypeError: params must be an object
Symptom: You get a TypeError when calling t().
Cause: You passed a non-object as the second argument.
Solution: Always pass an object, even for single values:
// Wrong
i18n.t('greeting', 'Alice')
// Right
i18n.t('greeting', { name: 'Alice' })
See Also
- Interpolation Concept - How interpolation works under the hood
- Pluralization Guide - Combine interpolation with plural forms
- Core API - Full
t()function documentation