Svelte Simple Lang is a lightweight library to manage multi-language (i18n) for your Svelte project. It comes with a simple setup, built-in support for lazy loading of language files, nested keys, pluralization, parameter interpolation, and type safety.
npm install svelte-simple-lang
When using createLang() you need to provide:
| Property | Type | Required | Description |
|---|---|---|---|
defaultLocale |
string |
✅ Yes | The default language to use at startup |
defaultSource |
object |
✅ Yes | Language data for the default locale (eager loaded) |
sources |
object |
✅ Yes | Map of locale to language data (eager or lazy-loaded) |
maxCachedLocales |
number |
❌ No | Max concurrent locales in memory (default: 5, min: 2) |
// src/lib/lang/i18n.ts
import createLang from 'svelte-simple-lang';
import id from './id.json' with { type: 'json' };
const i18n = createLang({
// Required: default locale and its data (must be eagerly loaded)
defaultLocale: 'id',
defaultSource: id,
// Required: all available locales (can be eager or lazy-loaded)
sources: {
id: id,
en: () => import('./en.json')
},
// Optional: configure cache size (default: 5, min: 2)
maxCachedLocales: 5
});
export const { availableLocales, getLocale, resetLocale, setLocale, setDefaultLocale, t } = i18n;
export default i18n;
| Function | Returns | Description |
|---|---|---|
t(key, params) |
string |
Translate a key with optional parameters |
setLocale(locale) |
Promise<boolean> |
Switch to locale (async, returns success status) |
getLocale() |
string |
Get currently active locale |
resetLocale() |
Promise<boolean> |
Reset to default locale (async, returns success status) |
setDefaultLocale(locale) |
Promise<boolean> |
Set as default and switch (async, returns success status) |
availableLocales |
string[] |
Array of all available locale codes |
All async methods return Promise<boolean>:
true = successfully completedfalse = failed (error logged to console)en.json
{
"world": "World",
"hello_{name}": "Hello {name}",
"you_have_{count}_apple": "You have {count} apple",
"you_have_{count}_apple_plural": "You have {count} apples",
"you_have_{count}_apple_zero": "You have no apples",
"menu": {
"home": "Home",
"about": "About"
}
}
id.json
{
"world": "Dunia",
"hello_{name}": "Halo {name}",
"you_have_{count}_apple": "Kamu punya {count} apel",
"you_have_{count}_apple_plural": "Kamu punya {count} apel",
"you_have_{count}_apple_zero": "Kamu tidak punya apel",
"menu": {
"home": "Beranda",
"about": "Tentang"
}
}
Key Features:
t('menu.home')){paramName} syntax_plural for count > 1, _zero for count === 0<script lang="ts">
import { browser } from '$app/environment';
import { setDefaultLocale, setLocale, getLocale, t, availableLocales } from '$lib/lang/i18n';
// Initialize saved locale preference
const initLocale = async () => {
const saved = (localStorage.getItem('locale') as 'en' | 'id') ?? 'id';
await setDefaultLocale(saved);
};
if (browser) {
initLocale();
}
const changeLanguage = async (newLocale: string) => {
const success = await setLocale(newLocale);
if (success) {
localStorage.setItem('locale', newLocale);
}
};
</script>
<h1>{t('world')}</h1>
<p>Count: {t('you_have_{count}_apple', { count: 5 })}</p>
{#each availableLocales as locale}
<button on:click={() => changeLanguage(locale)}>{locale}</button>
{/each}
// src/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types.js';
export const load: LayoutServerLoad = async ({ url, cookies }) => {
// Determine locale: from query param, cookie, or default
let lang = (url.searchParams.get('lang') ?? cookies.get('lang') ?? 'id') as 'en' | 'id';
// Validate locale
if (!['id', 'en'].includes(lang)) {
lang = 'id'; // fallback
}
return { lang };
};
<!-- src/routes/+page.svelte -->
<script lang="ts">
import { setDefaultLocale, setLocale, getLocale, t } from '$lib/lang/i18n';
const { data } = $props();
// Set locale from server
setDefaultLocale(data.lang);
const changeLanguage = async (newLocale: string) => {
const success = await setLocale(newLocale);
if (success) {
// Optional: save to database or cookies
}
};
</script>
<h1>{t('world')}</h1>
<button on:click={() => changeLanguage(getLocale() === 'en' ? 'id' : 'en')}>
Change Language
</button>
For advanced usage, error handling, best practices, caching strategies, and more:
→ See USAGE.md for full documentation
Built for enterprise reliability:
_zero, singular, and _plural formsPromise<boolean> for error detectionany typesMIT