Gathering detailed insights and metrics for vue-gettext
Gathering detailed insights and metrics for vue-gettext
Gathering detailed insights and metrics for vue-gettext
Gathering detailed insights and metrics for vue-gettext
npm install vue-gettext
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
278 Stars
271 Commits
55 Forks
36 Watching
19 Branches
27 Contributors
Updated on 04 Sept 2024
Minified
Minified + Gzipped
JavaScript (91.39%)
Vue (3.03%)
Makefile (2.41%)
HTML (2.37%)
Shell (0.57%)
CSS (0.23%)
Cumulative downloads
Total Downloads
Last day
5.2%
1,466
Compared to previous day
Last week
-7%
6,936
Compared to previous week
Last month
-0.7%
29,576
Compared to previous month
Last year
-3.7%
348,714
Compared to previous year
43
Translate Vue.js applications with gettext.
This project does not support Vue 3. Please, have a look at vue3-gettext for Vue 3 support.
Please make sure to read the Pull request guidelines before making a pull request.
Any help is greatly appreciated:
.vue
files, see #28vue-gettext
is not SSR compliant, see #51vue-gettext
is a plugin to translate Vue.js applications with gettext
. It relies on the GNU gettext toolset and easygettext
.
vue-gettext
work at a high level?Annotating strings: to make a Vue.js app translatable, you have to annotate the strings you want to translate in your JavaScript code and/or templates.
Extracting strings: once strings are annotated, you have to run extraction tools (gettext-extract
and some GNU gettext utilities) to run over a Vue.js app source tree and pulls out all strings marked for translation to create a message file. A message file is just a plain-text file with a .po
file extension, representing a single language, that contains all available translation strings as keys and how they should be represented in the given language.
Translating message files: a translator needs to fill out the translations of each generated .po
files.
Compiling translations: once all message files have been translated, use gettext-compile
to make the translated .po
files usable in a Vue app. This will basically merge all translated .po
files into a unique .json
translation file.
Dynamically render translated strings to the DOM: vue-gettext
currently uses a custom component for this.
vue-gettext
provide?a custom component
and a custom directive
to annotate strings in templates and dynamically render translated strings to the DOM
a set of methods to annotate strings in JavaScript code and translate them
a language
ViewModel exposed to every Vue instances that you can use to:
get all available languages (defined at configuration time)
get or set the current language (initially defined at configuration time)
access whatever you passed to the plugin mixin (defined at configuration time)
a global and reactive language
property added to Vue.config
you can use to get or set the current language outside of Vue instances
vue-gettext
depend on?gettext-extract
to extract annotated strings from template files and produce a .pot
(Portable Object Template) file.
gettext-compile
to produce the sanitized JSON version of a .po
file.
Some GNU gettext utilities to extract annotated strings from JavaScript files and generate .po
files
Those tools should be integrated in your build process. We'll show you an example later.
1npm install vue-gettext
Basic installation with ES6 modules:
1// ES6 2import Vue from 'vue' 3import GetTextPlugin from 'vue-gettext' 4import translations from './path/to/translations.json' 5 6Vue.use(GetTextPlugin, {translations: translations})
There are a number of options you can use to configure the vue-gettext
plugin:
Option | Type | Requirement | Description |
---|---|---|---|
autoAddKeyAttributes | {Boolean} | optional | If true , key attributes are auto-generated if not present in your code. See the key documentation and issues #29 and #66. Default value is false . Enable this option only if you know what you're doing. |
availableLanguages | {Object} | optional | An object that represents the list of the available languages for the app whose keys are local names (e.g. en or en_US ) and whose values are language names used for the display in UI, e.g. English (United States) . It's exposed in all Vue instances via vm.$language.available |
defaultLanguage | {String} | optional | The local name of the default language, e.g. en_US . This will be the current active language. It's exposed in all Vue instances via vm.$language.current |
muteLanguages | {Array} | optional | Discard warnings for missing translations for all languages of the list. This is useful to avoid messages from the language used in source code. |
languageVmMixin | {Object} | optional | A mixin that will be passed to the main languageVm instance (exposed via $language ) that can be used, for example, to add custom computed properties |
silent | {Boolean} | optional | Enable or disable logs/warnings for missing translations and untranslated keys. Default value is Vue.config.silent . |
translations | {Object} | required | The JSON file of the application's translations (produced by gettext-compile ). It's exposed as a Vue global property as Vue.$translations |
The key special attribute is primarily used as a hint for Vue's virtual DOM algorithm to identify VNodes when diffing ... Vue uses an algorithm that minimizes element movement and tries to patch/reuse elements of the same type in-place as much as possible.
Example:
1// ES6 2import Vue from 'vue' 3import GetTextPlugin from 'vue-gettext' 4import translations from './path/to/translations.json' 5 6Vue.use(GetTextPlugin, { 7 availableLanguages: { 8 en_GB: 'British English', 9 en_US: 'American English', 10 es_US: 'Español', 11 fr_FR: 'Français', 12 it_IT: 'Italiano', 13 }, 14 defaultLanguage: 'fr_FR', 15 languageVmMixin: { 16 computed: { 17 currentKebabCase: function () { 18 return this.current.toLowerCase().replace('_', '-') 19 }, 20 }, 21 }, 22 translations: translations, 23 silent: true, 24})
vm.$language
After the plugin initialization, a languageVm
Vue instance is injected
into every component as vm.$language
.
It exposes the following properties:
vm.$language.available
: an object that represents the list of the available languages (defined at configuration time)
vm.$language.current
: the current language (defined at configuration time)
whatever you passed to the plugin mixin
You can use vm.$language.current
and vm.$language.available
to e.g. easily build a language switch component with a single template:
1<template> 2 <div> 3 <select name="language" v-model="$language.current"> 4 <option v-for="(language, key) in $language.available" :value="key">{{ language }}</option> 5 </select> 6 </div> 7</template>
Vue.config.language
After the plugin initialization, a global and reactive language
property is added to Vue.config
that you can use to get or set the current language outside of Vue instances.
1> Vue.config.language 2'en_GB' 3> Vue.config.language = 'fr_FR'
You can use Vue.config.language
to e.g. configure a third party plugin in a filter:
1import moment from 'moment' 2import Vue from 'vue' 3 4const dateFormat = function (value, formatString) { 5 moment.locale(Vue.config.language) 6 return moment(value).format(arguments.length > 1 ? formatString : 'dddd D MMMM HH:mm:ss') 7}
Annotate your strings
Extract translations (make makemessages
)
Translate message files
Compile translations (make translations
)
Annotate | Extract | Translate | Compile
--------------------------------------------------------------------------------------------------------
component.js
component.vue ---> /tmp/template.pot ---> app/locale/fr_FR/LC_MESSAGES/app.po ---> app/translations.json
template.html
.html
or .vue
files)Strings are marked as translatable in your templates using either the translate
component or the v-translate
directive:
1<translate>Hello!</translate> 2<span v-translate>Hello!</span>
This will automatically be translated. For instance, in French, it might read Bonjour !.
1<translate>Hello!</translate>
1<translate :translate-n="count" translate-plural="%{ count } cars">%{ count } car</translate>
1<translate translate-context="Verb">Foo</translate>
1<translate translate-comment="My comment for translators">Foo</translate>
You can set up translation strings that are agnostic to how your app state is structured. This way you can change variable names within your app, it won't break your translation strings.
1<translate :translate-params="{name: userFullName}">Foo %{name}</translate>
It proves to be tricky to support interpolation with HTML content in Vue.js components because it's hard to access the raw content of the component itself.
So if you need to include HTML content in your translations you may use the directive.
The directive has the same set of capabilities as the component, except for translate-params which should be passed in as an expression.
1<p 2 v-translate='{count: carNumbers}' 3 :translate-n="carNumbers" 4 translate-plural="<strong>%{ count }</strong> cars" 5 translate-comment="My comment for translators" 6 > 7 <strong>%{ count }</strong> car 8</p>
translate
componentWhen rendered, the content of the translate
component will be wrapped in a span
element by default. You can also use another tag:
1<translate tag="h1">Hello!</translate>
Since interpolation inside attributes are deprecated in Vue 2, we have to use another set of delimiters. Instead of the "Mustache" syntax (double curly braces), we use %{
and }
:
1<translate>Hello %{ name }</translate>
Raw HTML in data is interpreted as plain text, not HTML. In order to output real HTML, you will need to use the render-html
attribute and set it to true
.
1<p 2 v-translate 3 render-html="true" 4 > 5 Hello %{ openingTag }%{ name }%{ closingTag } 6</p>
Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to XSS vulnerabilities. Only use HTML render-html="true"
on trusted content and never on user-provided content.
v-translate
with interpolationIt's not possible (yet) to detect changes on the parent component's data, so you have to add an expression to the directive to provide a changing binding value. This is so that it can do a comparison on old and current value before running the translation in its update
hook.
It is described in the official guide:
update: called after the containing component has updated, but possibly before its children have updated. The directive's value may or may not have changed, but you can skip unnecessary updates by comparing the binding's current and old values...
1<p 2 v-translate='{count: count, brand: brand}' 3 :translate-n="count" 4 translate-plural="<strong>%{ count }</strong> %{brand} cars" 5 translate-comment="My comment for translators" 6 > 7 <strong>%{ count }</strong> %{brand} car 8</p>
<translate>
or directive v-translate
with interpolation inside v-for
It's not possible (yet) to access the scope within v-for
, example:
1<p> 2 <translate v-for='name in names'>Hello %{name}</translate> 3 <span v-for='name in names' v-translate>Hello %{name}</span> 4</p>
Will result in all Hello %{name}
being rendered as Hello name
.
You need to pass in custom parameters for it to work:
1<p> 2 <translate v-for='name in names' :translate-params='{name: name}'>Hello %{name}</translate> 3 <span v-for='name in names' v-translate='{name: name}'>Hello %{name}</span> 4</p>
v-translate
with Vue components or Vue specific attributesIt's not possible (yet) to support components or attributes like v-bind
and v-on
. So make sure that your HTML translations stay basic for now.
For example, this is not supported:
1<p v-translate> 2 Please <button @click='doSomething'>click</button> here to view <my-account></my-account> 3</p>
.js
or .vue
files)Strings are marked as translatable in your Vue instances JavaScript code using methods attached to Vue.prototype
.
1vm.$gettext(msgid)
1vm.$ngettext(msgid, plural, n)
1vm.$pgettext(context, msgid)
1vm.$npgettext(context, msgid, plural, n)
You can use interpolation in your JavaScript using another method attached to Vue.prototype
: vm.$gettextInterpolate
.
1... 2methods: { 3 alertPlural (n) { 4 let translated = this.$ngettext('%{ n } foo', '%{ n } foos', n) 5 let interpolated = this.$gettextInterpolate(translated, {n: n}) 6 return window.alert(interpolated) 7 }, 8}, 9...
vm.$gettextInterpolate
dynamically populates a translation string with a given context object.
This should be a step in your build process and this can be done in several ways.
Here are the things we must do:
extracting annotated strings from templates (.html
and/or .vue
files),
extracting annotated strings from JavaScript code (.js
and/or .vue
files),
creating a main .pot
template based on the extracted strings,
creating editable .po
files for each available language.
You'll need to install easygettext
and use gettext-extract
to extract annotated strings from template files and produce a .pot
file.
You'll also need some GNU gettext utilities, namely msgmerge
, msginit
and msgattrib
to generate .po
files from the .pot
dictionary file.
We use a Makefile
with a makemessages
target to automate this step. To give you an example, I included a Makefile
with a makemessages
target in this project that you can include in your build process.
Extracting strings and generating .po
files becomes as easy as running:
1make makemessages
The translator needs to fill out the translations of each generated .po
files.
This can be done by you or outsourced to other firms or individuals since .po
files are the industry standard for multilingual websites.
There is also a wide range of translation tools available in the gettext ecosystem. Some of them are listed on Wikipedia.
This step focuses on making the translated .po
files usable in your Vue.js app.
Once translated, install easygettext
and use gettext-compile
to merge all translated .po
files into a unique .json
translation file.
Embed the .json
translation file back into your application. This is done only one time at vue-gettext
configuration time.
We use a Makefile
with a translations
target to automate this step.
Compiling translations becomes as easy as running:
1make translations
Look at the included Makefile
for an example.
translate
without VueFor convenience translate
can be imported directly in JavaScript files for cases where you need the translations from translations.json
outside of vue-gettext
(see #113):
1import {translate} from 'vue-gettext'; 2 3const {gettext: $gettext, gettextInterpolate} = translate; 4 5const str = $gettext('Hello, %{name}'); 6const strFR = $gettext('Hello, %{name}', 'fr'); 7const interpolated = gettextInterpolate(str, { name: 'Jerom' })
If you are using a template language, i.e. Pug.js in Single File Component within a webpack setup (using vue-loader), have a look at vue-webpack-gettext.
This plugin was inspired by:
systematic
for Makefile and
extraction of translatable strings.angular-gettext
vue-i18n
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 4/19 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
76 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn Morevue-webpack-gettext
Extract and compile translations with vue-gettext and vue-loader, i.e. for .vue files with <template lang='pug'></template>
gettext-extractor-vue
Extend gettext-extractor with the possibility to parse Vue single file components
vue-gettext-cli
Vue.js web application localization workflow command-line interface tool.
vue3-gettext
Translate Vue 3 applications with gettext