@qzlcorp/typed-i18n-vue
v1.1.0
Published
Vue bindings for @qzlcorp/typed-i18n
Maintainers
Readme
@qzlcorp/typed-i18n-vue
Vue 3 bindings for @qzlcorp/typed-i18n with full TypeScript support.

Watch how TypeScript catches translation key errors at compile time, ensuring type-safe i18n throughout your app.
Installation
pnpm add @qzlcorp/typed-i18n @qzlcorp/typed-i18n-vueUsage
Important: Key Type Safety
Translation key type safety depends on providing the reference type when defining a module:
const common = defineModule('common')<typeof enCommon>({
en: enCommon,
fr: frCommon,
}); // ✅ Keys validated at compile timeIf you omit the generic reference type, Vue runtime still works but invalid keys won’t be caught until runtime warnings appear.
Dynamic module loading: addModule() returns a new widened instance. To get types for newly added namespaces in the same scope, use the returned instance.
const i18n = createI18n({ locale: 'en', modules: { common } });
const dashboard = defineModule('dashboard')<typeof enDashboard>({ en: enDashboard, fr: frDashboard });
const i18n2 = i18n.addModule(dashboard); // widened type
i18n2.t('dashboard.title'); // ✅ Typed
i18n.t('dashboard.title'); // ❌ Type error (original instance)When using the plugin, if you need types for dynamically added modules in existing components, re-provide the updated instance or design your app to mount features after load.
Plugin API (Recommended)
import { createApp } from 'vue';
import { createI18n, defineModule } from '@qzlcorp/typed-i18n';
import { createI18nPlugin } from '@qzlcorp/typed-i18n-vue';
import App from './App.vue';
// Define your modules
const common = defineModule('common')<typeof enCommon>({
en: enCommon,
fr: frCommon,
});
// Create i18n instance
const i18n = createI18n({
locale: 'en',
fallbackLocale: 'en',
modules: { common },
});
// Install plugin
const app = createApp(App);
app.use(createI18nPlugin({ i18n }));
app.mount('#app');In Components
<script setup lang="ts">
import { useI18n } from '@qzlcorp/typed-i18n-vue';
const { t, locale, setLocale, locales } = useI18n();
// You can optionally narrow to a namespace for stricter key scope:
// const { t } = useI18n();
// const tCommon = ((key: `common.${string}`) => t(key))
</script>
<template>
<div>
<h1>{{ t('common.hello') }}</h1>
<p>Current locale: {{ locale }}</p>
<select :value="locale" @change="setLocale($event.target.value)">
<option v-for="loc in locales" :key="loc" :value="loc">
{{ loc }}
</option>
</select>
</div>
</template>Global Property
You can also use $t directly in templates:
<template>
<h1>{{ $t('common.hello') }}</h1>
<p>{{ $t('common.greeting', { name: 'World' }) }}</p>
</template>Provide/Inject Pattern (Alternative)
If you prefer not to use the plugin:
<script setup lang="ts">
import { provideI18n } from '@qzlcorp/typed-i18n-vue';
// In root component
provideI18n(i18n);
</script><script setup lang="ts">
import { useI18n } from '@qzlcorp/typed-i18n-vue';
// In child components
const { t } = useI18n();
</script>API
createI18nPlugin(options)
Creates a Vue plugin for i18n.
Options:
i18n- The i18n instance created withcreateI18n()
useI18n()
Composable that returns translation and locale management.
Returns:
t(key, params?)- Translate function with parameter interpolationt(key, options?)- Translate function with options (supportsreturnObjects)locale- Computed ref of current localesetLocale(locale)- Change locale (triggers reactivity)locales- Computed ref of all available localesi18n- Full i18n instance
<script setup lang="ts">
import { useI18n } from '@qzlcorp/typed-i18n-vue';
const { t, locale, setLocale, locales } = useI18n();
// Simple translation
const title = t('common.title');
// With parameters
const greeting = t('common.greeting', { name: 'Vue' });
// Get nested objects (i18next compatible)
const config = t('app.config', { returnObjects: true });
// Both params and returnObjects
const data = t('dashboard.stats', {
params: { count: 5 },
returnObjects: false
});
</script>
<template>
<div>{{ title }}</div>
</template>provideI18n(i18n) / injectI18n()
Alternative provide/inject pattern if you don't want to use the plugin.
Features
✅ Reactive - Automatic updates when locale changes
✅ Full Type Safety - All translation keys are typed
✅ Vue 3 Composition API - Built with modern Vue patterns
✅ Global Property - Use $t in templates
✅ Tree Shakeable - Only import what you use
Support
License
MIT © Q.Z.L Corp.
