@byjohann/vue-i18n
v1.3.0
Published
Lightweight internationalization plugin for Vue
Downloads
240
Maintainers
Readme
@byjohann/vue-i18n
Lightweight internationalization plugin for Vue.
Why bother creating another i18n library if Vue I18n seems to be the de-facto standard? Well, I was looking for a lightweight solution that solely covers the most basic use cases. I also wanted to learn, what a minimalistic i18n library would look like. So I built it.
Key Features
- 🗜
useI18n
composable - 🔃 Lazily add translations at runtime
- 📯 Global properties
$t
and$i18n
accessible in templates - 🦾 Strongly typed locales and messages
- 🌬️ Zero dependencies
Setup
# pnpm
pnpm add @byjohann/vue-i18n
# npm
npm i @byjohann/vue-i18n
# yarn
yarn add @byjohann/vue-i18n
Usage
[!TIP] 📖 Check out the playground
Before you can use @byjohann/vue-i18n
, you need to initialize the i18n
instance:
// plugins/i18n.ts
import { createI18n } from '@byjohann/vue-i18n'
const i18n = createI18n({
defaultLocale: 'en',
locales: ['en', 'de'],
messages: {
en: {
intro: 'Welcome, {name}',
},
de: {
intro: 'Willkommen, {name}',
},
},
})
export default i18n
Inside your app's entry point, import the i18n
instance and add it you Vue:
// main.ts
import { createApp } from 'vue'
import i18n from './i18n'
const app = createApp(App)
app.use(i18n)
app.mount('#app')
Done! Now you can retrieve translated keys in your components:
const { locale, t, setLocale } = useI18n()
locale.value // `en`
t('intro', { name: 'World' }) // `Welcome, World`
// Set new locale
setLocale('de')
locale.value // `de`
t('intro', { name: 'World' }) // `Willkommen, World`
Strict Locale and Messages Types
Typed locales and messages will help you to avoid typos and make your code more robust. To narrow the type of your locales, you can create a Locale
type and pass it to the useI18n
composable.
Properties like locale
, locales
and messages
will be typed accordingly.
import type enMessages from './locales/en.json'
type Messages = typeof enMessages
type Locale = 'en' | 'de'
const { locale, messages } = useI18n<Locale, Messages>()
messages.fr = { // The property "fr" is not assignable to type "LocaleMessages<Locale>".
// ...
}
Message Formatting
General Formatting
const messages = {
en: {
intro: 'Hello World'
}
}
Template
<p>{{ t('intro') }}</p>
Output
<p>Hello World</p>
Named Formatting
const messages = {
en: {
intro: '{msg} World'
}
}
Template
<p>{{ t('intro', { msg: 'My' }) }}</p>
Output
<p>My World</p>
List Formatting
const messages = {
en: {
intro: '{0} World'
}
}
Template
<p>{{ t('intro', ['My']) }}</p>
Output
<p>My World</p>
List formatting also accepts array-like objects:
Template
<p>{{ t('intro', {'0': 'My'}) }}</p>
Output
<p>My World</p>
Auto-Load Translations
To automatically load translations, you can use the glob import from Vite to load all translation files from a directory.
import { createI18n } from '@byjohann/vue-i18n'
import type { LocaleMessages } from '@byjohann/vue-i18n'
// Auto-load translations
const messages = Object.fromEntries(
Object.entries(
import.meta.glob<LocaleMessages>('./locales/*.json', { eager: true })
).map(([key, value]) => [key.slice(10, -5), value])
)
const i18n = createI18n({
defaultLocale: 'en',
locales: Object.keys(messages),
messages
})
export { i18n }
API
$t
& $i18n
The properties $t
as well as $i18n
are available globally in your templates.
Example:
<p>{{ $t('intro') }}</p>
useI18n
To access the current i18n instance, you can import the useI18n
composable from @byjohann/vue-i18n
. The useI18n
composable is available your <script setup>
blocks or the setup
function of your components.
Example
import { useI18n } from '@byjohann/vue-i18n'
const {
defaultLocale,
locale,
locales,
messages,
t,
setLocale,
getLocale
} = useI18n()
console.log(locales) // `['en', 'de']`
console.log(t('foo')) // `bar`
Type Declaration
function useI18n<
Locale extends string = string,
Messages extends Record<string, unknown> = Record<string, unknown>
>(): I18nInstance<Locale>
interface I18nInstance<
Locale extends string = string,
Messages extends Record<string, unknown> = Record<string, unknown>
> {
defaultLocale: Locale
locale: ComputedRef<Locale>
locales: readonly Locale[]
messages: LocaleMessages<Locale, Messages>
t: <const T>(key: T, params?: MessageParameters) => string
setLocale: (locale: Locale) => void
getLocale: () => string
}
💻 Development
- Clone this repository
- Enable Corepack using
corepack enable
- Install dependencies using
pnpm install
- Start development server using
pnpm run dev
insideplayground
License
MIT License © 2022-PRESENT Johann Schopplich
MIT License © 2022-2023 LeanERA GmbH