svelte-i18n

Lightweight i18n library for Svelte 5, inspired by vue-i18n, providing a complete internationalization solution.

Features

  • Create i18n instances via createI18n with flexible configuration
  • Reactive translation function t(), supports nested keys and namespaces
  • String interpolation with {name} placeholders
  • Pluralization with custom pluralization rules
  • Fallback locale: auto fallback when translation is missing
  • Dynamic loading / merging of language messages
  • Automatic browser language detection
  • localStorage persistence
  • Full TypeScript type definitions
  • Compatible with CommonJS and ES Modules

Installation

npm Install

# npm
npm install @free-walk/svelte-i18n

# cnpm(国内镜像)
cnpm install @free-walk/svelte-i18n

# yarn
yarn add @free-walk/svelte-i18n

# pnpm
pnpm add @free-walk/svelte-i18n

Peer Dependencies

Make sure the following dependencies are installed:

npm install svelte

ES Module Import

import { createI18n } from '@free-walk/svelte-i18n'

CommonJS Require

const { createI18n } = require('@free-walk/svelte-i18n')

CDN Usage

You can also use it directly via CDN (for quick prototyping or online demos):

<script src="https://unpkg.com/@free-walk/svelte-i18n@1.2.0/dist/svelte-i18n.iife.js"></script>
<script>
  // 全局变量 SvelteI18n
  const i18n = SvelteI18n.createI18n({ locale: 'zh', messages: { ... } })
</script>

Quick Start

import { createI18n } from '@free-walk/svelte-i18n'

const i18n = createI18n({
  locale: 'zh',
  fallbackLocale: 'en',
  messages: {
    zh: {
      greeting: '你好 {name}',
      nav: { home: '首页', about: '关于' },
    },
    en: {
      greeting: 'Hello {name}',
      nav: { home: 'Home', about: 'About' },
    },
  },
})

// 在 Svelte 组件中使用
const { t, locale } = i18n
<!-- App.svelte -->
<script>
  import { i18n } from './i18n'
  const { t, locale, setLocale } = i18n
</script>

<h1>{$t('greeting', { name: 'World' })}</h1>
<p>{$t('nav.home')}</p>
<button onclick={() => setLocale($locale === 'zh' ? 'en' : 'zh')}>
  Switch Language
</button>

createI18n

Factory function to create an i18n instance, returning a complete internationalization toolkit.

Function Signature

function createI18n(options: I18nOptions): I18nInstance

Configuration

PropertyTypeRequiredDescription
localestringYesCurrent locale identifier (required)
fallbackLocalestringNoFallback locale, used when translation is missing
messagesLocaleMessagesNoMulti-locale messages mapping object
pluralizationRulesPluralizationRulesNoCustom pluralization rules mapping
persistbooleanNoWhether to persist to localStorage
persistKeystringNolocalStorage storage key name
detectBrowserLocalebooleanNoWhether to auto-detect browser language
availableLocalesstring[]NoAvailable locales list (for browser detection matching)

Translation

Translation function (derived store, reactive)

// 基础翻译
$t('greeting')

// 嵌套键
$t('nav.home')

// 带插值
$t('greeting', { name: 'World' })

// 命令式翻译(非响应式)
i18n.translate('greeting', { name: 'World' })

Interpolation

Use {name} placeholders for string interpolation.

// 语言消息
messages: {
  zh: { welcome: '欢迎 {name},你有 {count} 条消息' },
  en: { welcome: 'Welcome {name}, you have {count} messages' },
}

// 使用
$t('welcome', { name: '张三', count: 5 })
// => '欢迎 张三,你有 5 条消息'

Pluralization

Use | to separate plural forms, pass a number to auto-select.

Message format: zero | singular | plural

// 语言消息
messages: {
  en: {
    apple: 'no apple | one apple | {count} apples',
    car: 'no cars | {count} car | {count} cars',
  },
}

// 使用:传入数字作为第二个参数
$t('apple', 0)  // => 'no apple'
$t('apple', 1)  // => 'one apple'
$t('apple', 5)  // => '5 apples'

Custom Pluralization Rules

const i18n = createI18n({
  locale: 'ru',
  messages: { ru: { ... } },
  pluralizationRules: {
    ru: (choice, choicesLength) => {
      if (choice === 0) return 0
      const teen = choice > 10 && choice < 20
      const lastDigit = choice % 10
      if (lastDigit === 1 && !teen) return 1
      if (lastDigit >= 2 && lastDigit <= 4 && !teen) return 2
      return choicesLength < 4 ? 2 : 3
    },
  },
})

Dynamic Loading

Supports dynamic loading or merging of language messages at runtime.

loadMessages: overwrite loading

// 覆盖式加载
i18n.loadMessages('ja', {
  greeting: 'こんにちは {name}',
})
i18n.setLocale('ja')

mergeMessages: incremental merge

// 增量合并(不覆盖已有键)
i18n.mergeMessages('zh', {
  newModule: {
    title: '新模块',
    desc: '描述',
  },
})

API Reference

Property / MethodTypeDescription
localeWritable<string>Current locale (writable store, reactive)
tReadable<(key, params?) => string>Translation function (derived store, reactive)
translate(key, params?)(key, params?) => stringImperative translation (non-reactive, reads current value)
setLocale(locale)(string) => voidSwitch locale
getLocale()() => stringGet current locale
loadMessages(locale, messages)(string, Messages) => voidDynamically load messages (overwrites existing)
mergeMessages(locale, messages)(string, Messages) => voidMerge messages (does not overwrite existing keys)
availableLocales()() => string[]Get all registered locales
hasKey(key, locale?)(string, string?) => booleanCheck if a key has a translation

createSimpleI18n

Simplified factory function, only needs default locale and messages, auto-infers fallback locale.

import { createSimpleI18n } from '@free-walk/svelte-i18n'

const { t, locale, toggle } = createSimpleI18n('zh', {
  zh: {
    hello: '你好',
    nav: { home: '首页' },
  },
  en: {
    hello: 'Hello',
    nav: { home: 'Home' },
  },
})

// toggle() — Cycle through available locales
MethodDescription
toggle()Cycle through available locales