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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@juit/vue-i18n

v0.2.42

Published

Juit I18n for Vue =================

Readme

Juit I18n for Vue

The @juit/vue-i18n package provides a minimalistic plugin for VueJS (v. 3) to support basic internationalization (translations, numbers, and date formats).

It heavily relies on the Intl.Locale, Intl.NumberFormat, and Intl.DateTimeFormat global objects widely supported by modern browsers.

It also deeply integrates with TypeScript to provide compile-time checking on required translation languages and translation keys.

Table of Contents

Installation

As usual, install with NPM (or the cool package-manager du jour):

npm install '@juit/vue-i18n'

And add the plugin to your Vue app:

import { createApp } from 'vue'
import { i18n } from '@juit/vue-i18n'
import MyApp from './app.vue'

const app = createApp(MyApp).use(i18n, {
  defaultLanguage: 'en',
  translations: {
    hello: {
      en: 'Hello, world!',
      de: 'Hallo, Welt!',
    },
  }
})

Configuration

The plugin can be configured with a simple string (the defaultLanguage) described below, or some options:

  • defaultLanguage: (required) the default language to use; all translations should be available in this language.
  • defaultTimeZone: the default time zone to use when formatting dates (defaults to the local time zone).
  • translations: an object containing the translations for the messages to translate, keyed by its identifier.
  • dateTimeFormats: date and time format aliases used formatting dates.
  • numberFormats: number format aliases used formatting numbers.

Date Time Format Aliases

Date time formatting aliases can be configured keyed by a simple string and values as Intl.DateTimeFormatOptions

import { createApp } from 'vue'
import { i18n } from '@juit/vue-i18n'
import MyApp from './app.vue'

const app = createApp(MyApp).use(i18n, {
  defaultLanguage: 'en',
  dateTimeFormats: {
    custom: {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
    },
  }
})

The default (overridable) formats are as follows:

 {
   // used when no alias or date time format is specified
   default: { dateStyle: 'medium', timeStyle: 'medium' },

   // generic formats
   short: { dateStyle: 'short', timeStyle: 'short' },
   medium: { dateStyle: 'medium', timeStyle: 'medium' },
   long: { dateStyle: 'long', timeStyle: 'long' },
   full: { dateStyle: 'full', timeStyle: 'full' },

   // date only formats
   date: { dateStyle: 'medium' },
   shortDate: { dateStyle: 'short' },
   mediumDate: { dateStyle: 'medium' },
   longDate: { dateStyle: 'long' },
   fullDate: { dateStyle: 'full' },

   // time only formats
   time: { timeStyle: 'medium' },
   shortTime: { timeStyle: 'short' },
   mediumTime: { timeStyle: 'medium' },
   longTime: { timeStyle: 'long' },
   fullTime: { timeStyle: 'full' },
}

Number Format Aliases

Similarly to date time, also number formatting aliases can be configured keyed by a simple string and values as Intl.NumberFormatOptions

import { createApp } from 'vue'
import { i18n } from '@juit/vue-i18n'
import MyApp from './app.vue'

const app = createApp(MyApp).use(i18n, {
  defaultLanguage: 'en',
  numberFormats: {
    speed: {
      style: 'unit',
      unit: 'kilometer-per-hour',
    }
  }
})

While there is no intrinsic default, each valid ISO-4217 currency code (e.g. EUR, USD, ...) can be used as an alias.

To configure the default number format use the default key.

Usage

In any component setup() method, you can use the useTranslator() function to get a hold on the Translator configured for the current app.

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator()

Switching language

To switch language, simply set the language, region or locale properties on the translator instance:

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator() // assuming the default locale is "en-US"

translator.region = 'CA'   // we have switched to Canada, and locale is now "en-CA"
translator.language = 'fr' // we have switched to French, and locale is now "fr-CA"

// or set the full `locale`
translator.locale = new Intl.Locale('de-AT')

Because of reactivity, all translations will be updated to the new locale.

Translating messages

The base function to translate messages is exposed as translator.t(...) or (within components) the $t(...) function.

This function takes a translation key (specified in the configuration phase, see above).

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator()

const hello = translator.t('hello')
// the "hello" string will be "Hello, world!" or "Hallo, Welt!"

It can also take an inline translation:

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator()

const panagram = translator.t({
  en: 'The quick fox jumped over the lazy dog',
  de: 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'
})

Parameterizing translations

Translations can include parameters by enclosing them in curly braces {param}.

For example:

const name = 'John Doe'

const string: translator.t({
  en: 'Your name is {name}'
  de: 'Ihr Name ist {name}'
}, { name })
// This will result in either "Your name is John Doe" or "Ihr Name ist John Doe"

When parameters are numbers, those will be formatted as numbers:

const string: translator.t({
  en: 'Score {points} points'
  de: 'Punktestand {points} Punkte'
}, { points: 1234.56 })
// This will result in "Score 1,234.56 points" or "Punktestand 1.234,56 Punkte"

Pluralization

The translator supports minimal rules for pluralization by separating translation messages with the | (pipe) character.

Messages can contain two variants singular|plural or three variants zero|singular|plural, with each variant used when the reference number to pluralize is either zero, one, or another number:

To contextualize the number, either use the n parameter, or use the tc(...) function which will take, as a second parameter, the reference number.

For example:

const string: translator.t({
  en: 'no cats | one cat | {n} cats'
  de: 'keine Katzen | eine Katze | {n} Katzen'
}, { n })
// This will result in "no cats" or "keine katzen" when "n" is zero,
// "one cat" or "eine Katze" when "n" is 1, or
// "1,234.56 cats" or "1.234,56 Katzen" when "n" is 1234.56

Is equivalent to:

const string: translator.tc({
  en: 'no cats | one cat | {n} cats'
  de: 'keine Katzen | eine Katze | {n} Katzen'
}, n)

Formatting numbers

The n(...) function can be used to format numbers in the current locale:

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator()

const number = translator.n(1234.5)
// the "number" string will be "1,234.5", "1.234,5" or whatever locale specified

A currency can be specified as a second parameter for quick formatting:

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator()

const amount = translator.n(1234.5, 'USD')
// the "amount" will be "$1,234.5", "1.234,5 $" or whatever locale specified

A full Intl.NumberFormatOptions set of options can also be specified as a second parameter to fine-tune the formatting.

The default format can be specified when configuring the plugin as the formats.numberFormat option (intentionally, there is no default).

Formatting dates

The d(...) function can be used to format date-and-time values in the current locale.

When the second parameter is a string, it is considered to be one of the aliases configured when the plugin is setup.

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator()

const dateTime = translator.d(new Date()) // e.g. '03.02.2025, 18:08:05' in de-DE
const dateOnly = translator.d(new Date(), 'date') // e.g. '03.02.2025' in de-DE
const dateTime = translator.d(new Date(), 'time') // e.g. '18:08:05' in de-DE

A full Intl.DateTimeFormatOptions set of options can also be specified as a second parameter to fine-tune the formatting.

The third parameter, if specified, can be used to force the time zone used when formatting the date. This is useful when time zones are specified in the definition of date format aliases (see above):

import { useTranslator } from '@juit/vue-i18n'

const translator = useTranslator()

translator.d(new Date(), 'full', 'Europe/Berlin')
// e.g. Monday, 3 February 2025 at 18:08:03 Central European Standard Time

Configuring Types

One of the keys to this package is to provide compile-time safety for all translation languages (we don't want to forget to translate a message in a new language) and translation keys (we don't want to mistype a translation key by accident).

To do so, we can merge the I18nConfiguration interface of this package with our specific configurations. Two properties are expected to be defined in the configuration:

  • languages: the list of supported languages for the application. These are ISO 639-1 language codes, and when specified, every translation must include a translation for each.
  • translationKeys: the list of translation keys known by the application. These are the arbitrary keys used to identify the messages to be translated with the t and tc methods of Translator.
  • dateTimeFormats: the date and time formats aliases used by the application.
  • numberFormats: the number formats aliases used by the application.

To configure the types, follow the example below:

const translations = {
  hello: { en: 'Hello, world!', de: 'Hallo, Welt!' }
} as const satisfies Translations

const dateTimeFormats = {
  // override the default format
  default: { dateStyle: 'short', timeStyle: 'short' },
  // add a new custom format
  custom: {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    weekday: 'short',
    timeZone: 'UTC',
  },
} as const satisfies DateTimeFormats

const numberFormats = {
  speed: { style: 'unit', unit: 'kilometer-per-hour' },
} as const satisfies NumberFormats

declare module '@juit/vue-i18n' {
  export interface I18nConfiguration {
    languages: 'de' | 'en',
    translationKeys: keyof typeof translations,
    dateTimeFormats: keyof typeof dateTimeFormats,
    numberFormats: keyof typeof numberFormats,
  }
}

const app = createApp(MyApp).use(i18n, {
  defaultLanguage: 'en',
  translations,
  dateTimeFormats,
  numberFormats,
})

In the example above, if any of the translation objects in our app is missing a language (either en or de), TypeScript will complain.

In the same way, if we pass any other string but hello to t(...) or tc(...), TypeScript will report the wrong key.

Also, date time format aliases will be augumented using the customizations specified in dateTimeFormats and numberFormats.

Legal Stuff