0.5.2 • Published 27 days ago
@svelte-intl/svelte-intl v0.5.2
svelte-intl
A straightforward internationalization (i18n) library for Svelte 5, leveraging Runes for reactivity and supporting the ICU Message Format for powerful localization features.
Features
- Svelte 5 Runes: Built with Svelte 5's reactive primitives (
$state
,$derived
). - ICU Message Format: Supports complex translations including plurals, selects, dates, numbers, etc.
- Type Safety: Automatically generates a types based on your provided translations.
- Simple API: Easy-to-use functions (
t
,setLocale
) and reactive state (locale
). - Rich Text Translation: Integrates seamlessly with Svelte Snippets for embedding complex HTML within translations.
Installation
Install with NPM
npm i @svelte-intl/svelte-intl
Install with Yarn
yarn add @svelte-intl/svelte-intl
Setup
Create Translation Files: Define your messages using ICU syntax in separate files per locale.
src/lib/translations/en-us.json
:{ "hello": "Hello!", "seeProfile": "{name}, Click to see <link>{gender, select, male {his} female {her} other {their}} profile</link>.", // ... other messages };
src/lib/translations/es-la.json
:{ "hello": "¡Hola!", "seeProfile": "{name}, Haz clic para ver <link>su perfil</link>", // ... other messages };
Configure
svelte-intl
: Create an entry point for your i18n configuration, typically in$lib/i18n/index.ts
. This file will initialize the library and export the necessary functions and state.src/lib/i18n/index.ts
:import enUs from "../translations/en-us.json"; import esLa from "../translations/es-la.json"; import { makeI18n } from "./i18n.svelte"; const { t, setLocale, locale, format } = makeI18n({ "en-us": en_us, "es-la": es_la, }, "en-us"); export { t, setLocale, locale, format };
vite.config.(ts|js)
// ... import { svelteIntl } from '@svelte-intl/svelte-intl/vite';
export default defineConfig(({ mode }) => {
return {
plugins: [
// ...
svelteIntl({
localesDir: './messages',
defaultLocale: 'en-us',
}),
],
// ...
}
})
```
Usage
Import the exported functions and state into your Svelte components.
<script lang="ts">
import { t, setLocale, type Locale, locale } from "$lib/i18n"; // Adjust path if needed
import type { Snippet } from "svelte";
// Example data for rich text
let name = $state("Martin");
let gender = $state<"male" | "female" | "other">("male");
// Snippet definition for rich text injection
// This snippet will be rendered inside the <link></link> placeholder in the ICU message
{#snippet link(content: Snippet)}
<a href="/user/{name}" class="text-blue-600 hover:underline">
{@render content()}
</a>
{/snippet}
</script>
<label>
Locale:
<select
class="border p-1 rounded"
value={locale.current}
onchange={(e) => {
// Update the locale using setLocale
// The 't' function and 'locale.current' will reactively update
setLocale((e.target as HTMLSelectElement)?.value as Locale);
}}
>
{#each locale.list as l}
<option value={l}>{l}</option>
{/each}
</select>
</label>
<hr class="my-4">
<h1>{t("hello")}</h1>
<p>
{@render t.rich("seeProfile", {
name: name, // Pass data for placeholders
gender: gender,
link: link // Pass the defined Svelte snippet
})}
</p>
<h2 class="mt-4">Current Locale: {locale.current}</h2>
<div class="mt-4">
<button onclick={() => { name = "Alice"; gender = "female"; }} class="p-1 border rounded bg-gray-100">
Change to Alice
</button>
<button onclick={() => { name = "Martin"; gender = "male"; }} class="p-1 border rounded bg-gray-100 ml-2">
Change to Martin
</button>
</div>
Explanation
- Import: Bring
t
,setLocale
,locale
, and theLocale
type from your setup file ("$lib/i18n"
). - Basic Translation (
t
): Use thet
function (which behaves like a Rune) directly in your template:{t("key")}
. It automatically updates when the locale changes viasetLocale
. - Locale Switching:
- Use
locale.list
to iterate over available locales (e.g., in a dropdown). - Use
locale.current
to display the currently active locale or bind it to the switcher's value. - Call
setLocale("new-locale")
to change the application's language. Thet
function andlocale.current
will react automatically.
- Use
- Rich Text Translation (t.rich):
- Define an ICU message in your translation file with placeholders for data and named placeholders for HTML content (e.g.,
<link />
). - In your Svelte component, define a {#snippet} with a name matching the placeholder in your ICU message (e.g.,
{#snippet link(content: Snippet)}
). This snippet receives the text content designated for the link from the ICU message structure (e.g., the words "Click here" if your ICU wasClick <link>here</link>
). Correction based on user's example: The ICU string shown is more complex ({gender, select, ... <link>...</link> ...}
), the snippet replaces the<link>...</link>
part. - Call
{@render t.rich("key", { dataPlaceholder: value, snippetPlaceholderName: snippetName })}
. Pass regular data and the defined snippet itself as values in the options object. The library renders the translated string, injecting the rendered snippet into the appropriate placeholder.
- Define an ICU message in your translation file with placeholders for data and named placeholders for HTML content (e.g.,
API
makeI18n(translations: Record<string, Record<string, string>>, defaultLocale: string)
: Factory function to initialize the i18n system. Requires an object mapping locale codes to translation dictionaries and the initial locale code.t(key: string, options?: Record<string, string | number>)
: Reactive Rune. Returns the translated string for the given key in the current locale. Supports basic ICU placeholder replacement (not rich text).t.rich(key: string, options: Record<string, any>)
: Function to handle translations containing rich text (HTML). Returns a renderable object. Options should include data for ICU placeholders and Svelte Snippets matching named placeholders in the ICU string. Use with{@render ...}
.setLocale(newLocale: Locale)
: Function to change the active locale. Triggers reactivity fort
andlocale
.locale
: Reactive Rune. Provides an object{ current: string, list: string[] }
containing the currently active locale code and a list of all available locale codes.Locale
: Exported TypeScript type representing the union of available locale strings (e.g.,"en-us" | "es-la"
).