A compiled, Svelte-first i18n library with Gettext-like syntax and ICU plurals.
| Example | Online IDE |
|---|---|
| SSR | |
| SPA |
Please follow the Setup Guide to install and configure sveltext.
Import the t tag and write your text naturally.
<script lang="ts">
import { t } from 'sveltext';
let name = 'John Doe';
</script>
<h1>{t`Welcome back, ${name}!`}</h1>
Sometimes you need to define translated text outside of Svelte's render cycle, such as in Zod schemas, navigation arrays, or constant files.
If you use t outside of a component, it will try to evaluate immediately before the dictionary might be loaded. Instead, use the msg tag. It marks the string for the CLI extractor and compiles it to a hash, but delays the actual dictionary lookup until you need it.
// src/lib/helpers.ts
import { msg } from 'sveltext';
export const errors = {
sync: msg`Error while syncing items`,
};
<script lang="ts">
import { t } from 'sveltext';
import { errors } from '$lib/helpers';
function goRefresh(success = true) {
if (success) {
itemCount = 1;
alert(t`Refreshed`);
return;
}
alert(t(errors.sync));
}
</script>
sveltext catches missing plural categories at compile-time. If you forget any of the categories, the Vite build will fail and point you to the exact line.
<script lang="ts">
import { plural } from 'sveltext';
let count = 5;
</script>
<p>
{plural(count, {
one: '# Apple',
other: '# Apples',
})}
<!-- This will be inlined during compile-time into "5 Apples" -->
{plural(5, {
one: '# Apple',
other: '# Apples',
})}
</p>
Because sveltext is content-addressed, having the same Home t call 50 times in your app will only generate one entry in your dictionary. If you need the same word translated differently based on context, use the c() wrapper.
<script lang="ts">
import { c, t } from 'sveltext';
</script>
<h1>{t`Home`}</h1>
<p>{c('real_estate').t`Home`}</p>
<T> Component (Rich Text & Snippets)sveltext embraces Svelte 5's native {#snippet} architecture to translate strings with embedded HTML or components (like bold text or links).
Use the <T> component to interpolate rich UI elements without breaking the sentence structure for your translators.
<script lang="ts">
import { T, msg } from 'sveltext';
</script>
<T msg={msg`Toolbar: {refresh} {refreshFail}`}>
{#snippet refresh()}
<button type="button" onclick={() => goRefresh(true)}>
{t`Refresh`}
</button>
{/snippet}
{#snippet refreshFail()}
<button type="button" onclick={() => goRefresh(false)}>
{t`Refresh (fail)`}
</button>
{/snippet}
</T>
Because sveltext is Svelte 5 native, your interpolated snippets can contain fully interactive components, state bindings, or any complex UI you need.
Run the extraction script to scan your codebase for translatable messages.
npx sveltext extract
The API design and AOT-compilation philosophy were heavily inspired by Lingui, svelte-i18n-lingui and ttag. sveltext is a ground-up rewrite specifically designed to lerverage the Svelte 5 compiler and Vite ecosystem for zero-overhead integration.