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 🙏

© 2024 – Pkg Stats / Ryan Hefner

voo-i18n

v1.0.10

Published

A small package for implementing translations in Vue.js

Downloads

637

Readme

vue-i18n

A small package for implementing translations in Vue.js. Instead of using a dot based key to fetch a translated string, it just uses the default string itself as the key.

In short {{ $t('Hello world') }} instead of {{ $t('messages.hello_world') }}.

Better yet: {{ 'Hello world' | translate }}

Compatibility

Designed for Vue 1, currently does not support Vue 2 See a rough demo.

Installation

npm install voo-i18n

import Vue from 'vue'
import i18n from 'voo-i18n'

const translations = {
  'es': {
    'Hello world': 'Hola Mundo'
  },
  'fr': {
    'Hello world': 'Bonjour le monde'
  },
  'pirate': {
    'Hello world': 'Land ho!'
  }
}

Vue.use(i18n, translations)

Usage

Set a default locale in the root data of your application.

<template>
  <h1>{{ 'Hello world' | translate }}</h1>
</template>

<script>
  export default {
    data() {
      return {
        locale: 'en'
      }
    }
  }
</script>

And then the translations will be reactive to changes in the locale value.

Override locale

You can override the root locale by passing in the locale param

<h1>{{ $t('Hello world', { locale: 'es' }) }}</h1>

Fallback locales

Localization carries the problem of different languages having different dialects. For example, french vs. canadian french. You can make distinctions as such:

export default {
  'fr': {
    'Hello world': 'Bonjour le monde',
    'Goodbye': 'Au Revoir'
  },
  'fr_CA': {
    'Hello world': 'Bonjour tout le monde, du Canada'
  }
}

When the locale is set to fr_CA, {{ 'Goodbye' | translate }} still translates to 'Au Revoir'. You can also use a hyphen instead of an underscore if you prefer: fr-CA.

Variable arguments

Don't do this

<p>{{ 'You have used' | translate }} {{ count }} {{ 'out of' | translate }} {{ limit }}</p>
'es': {
  'You have used': 'Ha utilizado',
  'out of': 'fuera de'
},

Do this

<p>{{ $t('You have used {count} out of {limit}', {count, limit}) }}</p>
'es': {
  'You have used {count} out of {limit}': 'Ha utilizado {count} de los {limit}'
},

Inline HTML

It's often the case that your sentences will not form nice little compartmentalized strings like Hello world. Often you'll get HTML spliced in the middle.

Don't do this

  <p>{{ 'Please perform' | translate }} <a href="#" @click.prevent="action">{{ 'this action' | translate }}</a> {{ 'to complete the task' | translate }}</p>
'es': {
  'Please perform': 'Por favor, realice',
  'this action': 'esta acción',
  'to complete the task': 'para completar la tarea'
},

Do this

<p v-locale="$root.locale" key="Please perform |this action| to complete the task">
    <span></span>
    <a href="#" @click.prevent="action"></a>
    <span></span>
</p>
'es': {
  'Please perform |this action| to complete the task': 'Por favor, realice |esta acción| para completar la tarea'
},
Important:

The directive element only expects to have children 1 level deep. So <span v-locale="es" key="a|b"><a><b></b></a></span> will incorrectly render as <span><a>a</a></span>. I haven't found an elegant solution around this yet. The main goal of this repo is to retain lingual context in translations and logical context in components, so it's an acceptable sacrifice for the time being, but if you have a solution please notify me.

All Together Now!

<div v-locale="$root.locale" key="Thanks for signing up! Confirm |{email} is correct| to continue to the site." :replace="{ email: email }">
  <span></span>
  <a href="#" @click="confirm"></a>
  <span></span>
</div>
'es': {
  'Thanks for signing up! Confirm |{email} is correct| to continue to the site': 'Gracias por registrarte! Confirmar |{email} es correcta| para continuar al sitio'
},

Tips

Catching missing translations

If you provide translations for a locale and attempt to translate a string that is missing from the set that your provided, it will just fall back to the original string. If you have debug mode enabled, a warning will be sent to the browser console to help you maintain translations.

Recommended folder structure

In the root of your main javascript folder, create an i18n folder. Create map.js

import es from './es'
import it from './it'

export let locales = [
  {
    value: 'es',
    name: 'Spanish',
    native: 'Español',
  },
  {
    value: 'it',
    name: 'Italian',
    native: 'italiano',
  }
]

export default {
  es, it
}

And the respective translation files es.js and it.js

// es.js
export default {
  'Hello world': 'Hola mundo',
  ...
  (however many hundreds more translations)
}

This way you can hand a single file to a human translator, and you can just import all translations.

import translations from './i18n/map'
Vue.use(i18n, translations)

later you can import the locales separately to list a dropdown or something

<template>
  <a v-for="locale in locales"  @click.prevent="setLanguage(locale.value)">
    {{ locale.native }}
  </a>
</template>

<script>
import { locales } as locale_list from './i18n/map'

export default {
  computed: {
    locales() {
      return locale_list;
    }
  },
  methods: {
    setLanguage(value) {
      this.$root.locale = value;
    }
  }
}
</script>