npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@svelte-intl/svelte-intl

v0.5.2

Published

A straightforward internationalization (i18n) library for Svelte 5, leveraging Runes for reactivity and supporting the ICU Message Format for powerful localization features.

Readme

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

  1. 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
      };
  2. 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

  1. Import: Bring t, setLocale, locale, and the Locale type from your setup file ("$lib/i18n").
  2. Basic Translation (t): Use the t function (which behaves like a Rune) directly in your template: {t("key")}. It automatically updates when the locale changes via setLocale.
  3. 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. The t function and locale.current will react automatically.
  4. 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 was Click <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.

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 for t and locale.
  • 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").