Vue-i18n: Small issue when using translation keys as default language

Created on 6 Feb 2018  路  2Comments  路  Source: kazupon/vue-i18n

Hello,

Personally, I'm not a big fan of declaring my translation strings via keywords (privacyPolicy in the following example), like so:

const messages = {
  en: {
    privacyPolicy: 'Privacy Policy'
  },
  de: {
    privacyPolicy: 'Datenschutzerkl盲rung'
  }
}

I normally split the messages up into language files and then use the English version as keys, whenever it makes sense:

export default {
  'Privacy Policy': 'Datenschutzerkl盲rung'
}

This comes with a couple benefits. First, a translator won't have to search around for the actual string to translate and secondly, it allows me to write code like the following example, kinda like gettext. To me, this is cleaner, cause I know exactly what's going on:

<a href="/privacy-policy">{{ $t('Privacy Policy') }}</a>

The only issue I have with this approach is that I still need to maintain an English translation file cause when the key is used as a fallback, no substitutions are done:

<p>{{ $t('Hello {user}', { user: 'Bruce Banner' }) }}</p>

The above only works with an English translation file like so, which seems kinda silly:

export default {
  'Hello {user}': 'Hello {user}'
}

It'd be great if there was a solution to this issue, maybe a constructor option to parse fallback keys. It's not a big deal really, but it does mess with my OCD tendencies a bit ;)

Most helpful comment

I solved it differently, actually. I use the English lang file as a translation template with empty values now. When initialising vue-i18n I then copy the keys across to the values for the English strings.

All 2 comments

I solved it differently, actually. I use the English lang file as a translation template with empty values now. When initialising vue-i18n I then copy the keys across to the values for the English strings.

Another solution, if you don't want to manage empty translations file, could be to overwrite the missing handler (although you trade off some performance):

export const i18n = new VueI18n({
    ...
    missing: (locale, key, vm) => {
        var messages  = i18n.getLocaleMessage(locale);
        messages[key] = key;
        i18n.setLocaleMessage(locale, messages);
    },
});

Update
Another "hacky" solution that doesn't not cause rerendering like the missing handler is to extend the internal _translate method and populate the source language messages before returning the end result, eg:

const sourceMessages = {};
const originalTranslate = VueI18n.prototype._translate;
VueI18n.prototype._translate = function (messages, locale, fallback, key, host, interpolateMode, args) {
    if (!sourceMessages[key]) {
        sourceMessages[key] = key;
    }

    return originalTranslate.apply(this, arguments);
};

export var i18n = new VueI18n({
    locale:         'en-US',
    fallbackLocale: 'en-US',
    messages:       {'en-US': sourceMessages},
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

leo108 picture leo108  路  15Comments

bonchevski picture bonchevski  路  14Comments

WangShayne picture WangShayne  路  57Comments

gmarineau picture gmarineau  路  16Comments

flaird picture flaird  路  15Comments