Complete API reference for sveltekit-i18n – the complete i18n solution for SvelteKit with @sveltekit-i18n/parser-default included.
sveltekit-i18n includes all configuration options from @sveltekit-i18n/base, plus specific options for the default parser.
import i18n from 'sveltekit-i18n';
/** @type {import('sveltekit-i18n').Config} */
const config = {
loaders: [/* ... */],
parserOptions: {/* parser-default specific options */},
// All @sveltekit-i18n/base options available
};
export const { t, locale, locales, loading, loadTranslations } = new i18n(config);The following options work exactly as in @sveltekit-i18n/base:
loaders– Define how and when translations loadtranslations– Synchronous translationspreprocess– Transform translation datainitLocale– Initialize with specific localefallbackLocale– Fallback when translation missingfallbackValue– Default value for missing keyscache– Server-side cache durationlog– Logging configuration
📖 Full documentation: @sveltekit-i18n/base API docs
import i18n from 'sveltekit-i18n';
/** @type {import('sveltekit-i18n').Config} */
const config = {
// Common translations loaded on every page
loaders: [
{
locale: 'en',
key: 'common',
loader: async () => (await import('./en/common.json')).default,
},
{
locale: 'cs',
key: 'common',
loader: async () => (await import('./cs/common.json')).default,
},
],
// Optional: Configure default parser
parserOptions: {
modifierDefaults: {
number: { minimumFractionDigits: 2 },
},
},
};
export const { t, locale, locales, loading, loadTranslations } = new i18n(config);sveltekit-i18n uses @sveltekit-i18n/parser-default which supports placeholders and modifiers.
Configure default formatting options for built-in modifiers.
const config = {
parserOptions: {
modifierDefaults: {
number: {
// Intl.NumberFormat options
minimumFractionDigits: 0,
maximumFractionDigits: 2,
},
date: {
// Intl.DateTimeFormat options
dateStyle: 'medium',
},
ago: {
// Intl.RelativeTimeFormat options
numeric: 'auto',
format: 'auto', // 'auto' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'
},
currency: {
// Intl.NumberFormat currency options
style: 'currency',
currency: 'USD',
ratio: 1, // Conversion ratio
},
},
},
};Control how numbers are formatted:
const config = {
parserOptions: {
modifierDefaults: {
number: {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
},
},
},
};Translation:
{
"price": "Price: {{value:number;}}"
}Usage:
$t('price', { value: 99 })
// → "Price: 99.00" (with defaults)
// Without defaults → "Price: 99"Override per translation:
$t('price', { value: 99.999 }, { minimumFractionDigits: 3 })
// → "Price: 99.999"Control date formatting:
const config = {
parserOptions: {
modifierDefaults: {
date: {
dateStyle: 'full', // 'full' | 'long' | 'medium' | 'short'
timeStyle: 'short', // 'full' | 'long' | 'medium' | 'short'
// Or use individual options:
// year: 'numeric',
// month: 'long',
// day: 'numeric',
},
},
},
};Translation:
{
"published": "Published: {{date:date;}}"
}Usage:
$t('published', { date: new Date('2024-01-15') })
// → "Published: Monday, January 15, 2024" (with dateStyle: 'full')Control relative time formatting:
const config = {
parserOptions: {
modifierDefaults: {
ago: {
numeric: 'auto', // 'auto' | 'always'
format: 'auto', // 'auto' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'
},
},
},
};Translation:
{
"updated": "Updated {{time:ago;}}"
}Usage:
const oneHourAgo = Date.now() - 3600000;
$t('updated', { time: oneHourAgo })
// → "Updated 1 hour ago" (with numeric: 'auto')
// → "Updated in 1 hour" (with numeric: 'always')Format option:
// Auto-detect best unit
ago: { format: 'auto' } // Uses most appropriate unit
// Force specific unit
ago: { format: 'day' } // Always show in daysControl currency formatting:
const config = {
parserOptions: {
modifierDefaults: {
currency: {
style: 'currency',
currency: 'EUR', // Default currency
ratio: 1, // Exchange rate conversion
},
},
},
};Translation:
{
"total": "Total: {{amount:currency;}}"
}Usage:
$t('total', { amount: 99.99 })
// → "Total: €99.99" (with currency: 'EUR')With conversion ratio:
const config = {
parserOptions: {
modifierDefaults: {
currency: {
currency: 'CZK',
ratio: 25, // 1 EUR = 25 CZK
},
},
},
};
$t('total', { amount: 10 }) // 10 EUR
// → "Total: 250 CZK" (10 * 25)Override per translation:
$t('total', { amount: 99.99 }, { currency: 'GBP' })
// → "Total: £99.99"Add your own modifiers for specialized formatting.
const config = {
parserOptions: {
customModifiers: {
// Modifier name → implementation
upper: ({ value }) => String(value).toUpperCase(),
lower: ({ value }) => String(value).toLowerCase(),
capitalize: ({ value }) => {
const str = String(value);
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
},
},
},
};Translation:
{
"title": "{{text:upper;}}",
"subtitle": "{{text:capitalize;}}"
}Usage:
$t('title', { text: 'hello world' })
// → "HELLO WORLD"
$t('subtitle', { text: 'hello world' })
// → "Hello world"Custom modifiers receive these parameters:
const config = {
parserOptions: {
customModifiers: {
myModifier: ({ value, options, props, defaultValue, locale }) => {
// value: the placeholder value
// options: parsed options from translation
// props: additional props from $t() call
// defaultValue: default value if set
// locale: current locale
return transformedValue;
},
},
},
};Example: Conditional modifier with options
const config = {
parserOptions: {
customModifiers: {
status: ({ value, options, defaultValue }) => {
const option = options.find(opt => opt.key === value);
return option?.value || defaultValue || value;
},
},
},
};Translation:
{
"order": "Status: {{status:status; pending:⏳ Pending; shipped:📦 Shipped; delivered:✅ Delivered; default:❓ Unknown;}}"
}Usage:
$t('order', { status: 'shipped' })
// → "Status: 📦 Shipped"Example: Truncate with props
const config = {
parserOptions: {
customModifiers: {
truncate: ({ value, props }) => {
const maxLength = props?.maxLength || 50;
const str = String(value);
return str.length > maxLength ? str.slice(0, maxLength) + '...' : str;
},
},
},
};Translation:
{
"description": "{{text:truncate;}}"
}Usage:
$t('description', { text: 'Very long text here...' }, { maxLength: 20 })
// → "Very long text here..."Example: Format with locale awareness
const config = {
parserOptions: {
customModifiers: {
phone: ({ value, locale }) => {
const number = String(value).replace(/\D/g, '');
if (locale === 'us' || locale === 'en') {
// US format: (123) 456-7890
return `(${number.slice(0,3)}) ${number.slice(3,6)}-${number.slice(6)}`;
} else if (locale === 'cs' || locale === 'cz') {
// Czech format: +420 123 456 789
return `+420 ${number.slice(0,3)} ${number.slice(3,6)} ${number.slice(6)}`;
}
return value;
},
},
},
};Translation:
{
"contact": "Call us: {{phone:phone;}}"
}Usage:
// In English (en)
$t('contact', { phone: '1234567890' })
// → "Call us: (123) 456-7890"
// In Czech (cs)
$t('contact', { phone: '123456789' })
// → "Call us: +420 123 456 789"sveltekit-i18n instances include all properties and methods from @sveltekit-i18n/base:
t– Translation functionl– Locale-specific translation functionlocale– Current locale (writable)locales– All available localesloading– Loading stateinitialized– Initialization statetranslations– All loaded translationsloadTranslations– Load translations for locale and routesetLocale– Change current localesetRoute– Update current route- And more...
📖 Full API reference: @sveltekit-i18n/base API docs
const { t, locale, locales, loading, loadTranslations } = new i18n(config);
// Translation function
$t('home.title') // Simple
$t('greeting', { name: 'Alice' }) // With variables
$t('price', { value: 99 }, { currency: 'EUR' }) // With props
// In .js files
t.get('home.title')
// Locale management
$locale // Current locale
locale.set('cs') // Change locale
$locales // ['en', 'cs', ...]
// Loading state
$loading // true/false
await loading.toPromise() // Wait for load
// Load translations
await loadTranslations('en', pathname) // In +layout.jssveltekit-i18n uses @sveltekit-i18n/parser-default for message interpolation.
Simple variable substitution:
{
"greeting": "Hello, {{name}}!",
"message": "You have {{count}} notifications."
}$t('greeting', { name: 'Alice' }) // → "Hello, Alice!"
$t('message', { count: 5 }) // → "You have 5 notifications."Fallback when variable is missing:
{
"welcome": "Welcome, {{name; default:Guest;}}!"
}$t('welcome', { name: 'Bob' }) // → "Welcome, Bob!"
$t('welcome', {}) // → "Welcome, Guest!"Transform values before display:
{
"population": "Population: {{count:number;}}"
}$t('population', { count: 1000000 })
// → "Population: 1,000,000"{
"published": "Published: {{date:date;}}"
}$t('published', { date: new Date() })
// → "Published: Jan 15, 2024"{
"updated": "Updated {{time:ago;}}"
}$t('updated', { time: Date.now() - 3600000 })
// → "Updated 1 hour ago"{
"price": "Price: {{amount:currency;}}"
}$t('price', { amount: 99.99 }, { currency: 'USD' })
// → "Price: $99.99"Show different text based on values:
{
"items": "You have {{count}} {{count; 1:item; default:items;}}."
}$t('items', { count: 1 }) // → "You have 1 item."
$t('items', { count: 5 }) // → "You have 5 items."Available: eq, ne, lt, lte, gt, gte
{
"stock": "{{count:gt; 0:In stock ({{count}}); default:Out of stock;}}",
"age": "{{age:gte; 18:Adult; default:Minor;}}",
"status": "{{value:eq; active:✓ Active; inactive:✗ Inactive; default:Unknown;}}"
}$t('stock', { count: 5 }) // → "In stock (5)"
$t('stock', { count: 0 }) // → "Out of stock"
$t('age', { age: 25 }) // → "Adult"
$t('age', { age: 15 }) // → "Minor"Combine placeholders and modifiers:
{
"notification": "You have {{count:gt; 0:{{count}} new {{count; 1:message; default:messages;}}!; default:no messages.;}}"
}$t('notification', { count: 1 })
// → "You have 1 new message!"
$t('notification', { count: 5 })
// → "You have 5 new messages!"
$t('notification', { count: 0 })
// → "You have no messages."📖 Complete syntax guide: parser-default documentation
Full TypeScript support with complete type definitions:
import i18n, { type Config } from 'sveltekit-i18n';
const config: Config = {
loaders: [
{
locale: 'en',
key: 'common',
loader: async () => (await import('./en/common.json')).default,
},
],
parserOptions: {
modifierDefaults: {
number: {
minimumFractionDigits: 2,
},
},
},
};
export const { t, locale, locales, loading, loadTranslations } = new i18n(config);What's Included:
- ✅ Type definitions for all configuration options
- ✅ Typed API methods and stores
- ✅ Generic types for custom parsers
- ❌ Automatic inference of translation keys (not built-in)
The library doesn't automatically infer translation keys from JSON files, but you can implement your own type-safe pattern:
// translations.d.ts - Define your translation key types
export interface TranslationParams {
'common.greeting': { name: string };
'common.items': { count: number };
'home.title': never; // No parameters
}
// translations.ts - Create typed wrapper (optional)
import i18n, { type Config } from 'sveltekit-i18n';
const config: Config = {
// ... configuration
};
export const { t, locale, locales, loading, loadTranslations } = new i18n(config);
// For stricter typing, you can create a wrapper:
// export function typedT<K extends keyof TranslationParams>(
// key: K,
// ...params: TranslationParams[K] extends never ? [] : [TranslationParams[K]]
// ): string {
// return t.get(key, ...(params as any));
// }This pattern provides compile-time checking but requires manual maintenance of the TranslationParams interface.
- Getting Started – Step-by-step tutorial
- Architecture Overview – How everything works
- Best Practices – Recommended patterns
- Troubleshooting – Common issues and solutions
- @sveltekit-i18n/base – Core functionality (for custom parsers)
- @sveltekit-i18n/parser-default – Default parser (included)
- @sveltekit-i18n/parser-icu – ICU message format parser
- Parsers Overview – All available parsers
- Multi-page App – Most common setup
- Locale Routing – SEO-friendly URLs
- All Examples – Complete list with live demos