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

@ilingo/vue

v6.1.1

Published

Vue 3 integration for ilingo — provide/inject, reactive locale, the <ITranslate> component, a v-t directive, and the useTranslation composable.

Readme

npm version npm downloads minzipped size main codecov Known Vulnerabilities Conventional Commits

Table of Contents

Installation

npm install @ilingo/vue --save

Usage

import { install } from '@ilingo/vue';
import { MemoryStore, defineCatalog, defineLocale, defineNamespace, defineTranslations } from 'ilingo';
import { createApp } from 'vue';

const store = new MemoryStore({
    data: defineCatalog([
        // locale: de
        defineLocale('de', [
            // namespace: app
            defineNamespace('app', [
                defineTranslations({ key: 'Hallo mein Name ist {{name}}' }),
            ]),
        ]),
        // locale: en
        defineLocale('en', [
            defineNamespace('app', [
                defineTranslations({ key: 'Hello my name is {{name}}' }),
            ]),
        ]),
    ]),
})

const app = createApp(/* */);
install(app, {
    store,
});
app.mount('#app');

<script setup>
    import { injectLocale, useTranslation } from '@ilingo/vue';

    const locale = injectLocale();
    const set = (value) => {
        locale.value = value;
    }
    
    const translation = useTranslation({
        namespace: 'app', 
        key: 'key', 
        data: {
            name: 'Paul'
        }
    });
</script>
<template>
    <div>
        <ITranslate path="app.key" :data="{'name': 'Peter'}"/>
        <!-- Hello my name is Peter -->
    </div>
    <div>
        {{ translation }}
        <!-- Hello my name is Paul -->
    </div>
    <button type="button" @click.prevent="set('en')">
        en
    </button>
    <button type="button" @click.prevent="set('de')">
        de
    </button>
</template>

SSR: the first render is not a placeholder

useTranslation (and <ITranslate>, <ITranslateT>, useScopedCatalog().t) wraps the asynchronous Ilingo.get() in a computedAsync, which needs an initial value before its promise settles. That initial value comes from Ilingo.getSync(), the synchronous read path, so with an in-memory catalog the first render is already the real string rather than the namespace.key placeholder (#988).

For server-side rendering that removes a whole class of bugs: the translated string is what lands in the SSR markup, and the client's first render matches it instead of warning

[Vue warn]: Hydration text mismatch in th
  - rendered on server: "Name"
  - expected on client: "app.name"

No opt-in, no payload plumbing. Stores that need I/O (a cold LoaderStore or FSStore, a remote adapter) can't answer synchronously. Those keys still start at the placeholder and settle a tick later; warm them before rendering if the server output matters. See the SSR recipe and getSync.

<ITranslateT>: slot-aware interpolation

<ITranslateT> lets a message string carry slot placeholders alongside the usual {{var}} interpolations. Each {slot} placeholder in the message is filled by a named scoped slot, so you can drop arbitrary VNodes (links, icons, bold runs) inline without splitting the message across multiple keys.

Message: "Hi {{user}}, please {cta} to continue."

<ITranslateT path="app.welcome" :data="{ user: 'Peter' }">
    <template #cta>
        <a href="/start">get started</a>
    </template>
</ITranslateT>
<!-- → <span>Hi Peter, please <a href="/start">get started</a> to continue.</span> -->
  • Rendered tag: <span> by default. Override with tag="p" etc.; pass tag="" to render a fragment with no wrapper.
  • Unfilled slot placeholders stay as literal {slot} text (no throw).
  • {{var}} placeholders that have no matching data key stay as literal {{var}}.

v-t directive

v-t writes the translation into the element's textContent and reacts to locale changes without remounting the element.

<p v-t="'app.greeting'"></p>

<p v-t="{ path: 'app.greet', data: { name: 'Peter' } }"></p>

<p v-t="{ namespace: 'cart', key: 'items', count: 3 }"></p>

The directive is registered globally during install(). Opt out per-app via install(app, { store, directives: false }).

useScopedCatalog: per-component message scope

Some components (modals, embedded widgets, marketing sections) carry their own strings. useScopedCatalog creates an Ilingo instance whose stores resolve scoped messages first, then fall back to the parent app's stores. The scoped instance is provided to descendants; siblings outside the component still see the parent's stores.

<script setup>
import { useScopedCatalog, useTranslation } from '@ilingo/vue';
import { defineCatalog, defineLocale, defineNamespace, defineTranslations } from 'ilingo';

// Returns { instance, t }. Use `t` inside the same component because
// Vue's provide/inject can't reach the current setup's own provides.
const { t } = useScopedCatalog({
    messages: defineCatalog([
        defineLocale('en', [
            defineNamespace('modal', [
                defineTranslations({ greeting: 'Welcome to the modal!' }),
            ]),
        ]),
    ]),
});

const greeting = t({ namespace: 'modal', key: 'greeting' });
</script>

Descendants can use plain useTranslation: they get the scoped instance via inject. On unmount, Vue's provides become unreachable and the scoped instance is garbage-collected.

License

Made with 💚

Published under MIT License.