vue-i18n icon indicating copy to clipboard operation
vue-i18n copied to clipboard

[Feature Request] i18n.te doesnt look for global locales

Open vladra opened this issue 5 years ago • 7 comments

Not sure if this a bug or a feature, but when I'm trying to check if global translation exists, te returns false for all translations, except component level locales.

Given global locale file en.yaml:

en:
  hello: 'Hello'

i18n.te('hello') returns false

In case I have hello tranlsation defined inside my component, it returns true as expected.

I've tried to check source code, and it seems te doesnt look for global locales intentionally.

Could you please confirm this, or should this be treated as a bug?

vladra avatar Mar 28 '19 14:03 vladra

That's not bug. But it's might be improved.

I personally think that te is not necessary. Because, we ship the application after we will test whether there is a translation missing. In the future, I'll plan to remove the te from vue-i18n.

kazupon avatar Apr 12 '19 11:04 kazupon

I can describe you my use case for this feature:

Sometimes backend returns list of error codes. On the UI side we try to translate them, and we do this dynamically. Because of big amount of different words to be translated we do this dynamically (translation lookup based on error code received from backend, like company.name), checking if error code exists in global locales. If it's absent, we display general error message. Otherwise, error code translated, and human readable message is shown.

vladra avatar Apr 15 '19 10:04 vladra

+1 for me, simmilar situation with dynamic translation of strings

akadlec avatar Jul 18 '19 20:07 akadlec

+1 same use case as @vladra

KevinTanjung avatar Aug 01 '19 09:08 KevinTanjung

+1 same as @vladra

sense-it-gmbh avatar Sep 17 '19 12:09 sense-it-gmbh

@vladra

You could use this approach:

const errorCode = '404' // some error code
const path = `$dynamic.error.${errorCode}.text`
const locale = this.$i18n.locale

this.$root.$options.i18n.te(path, locale)

Obviously this will only work if it is a global path.

Another use case:

We have generic components that get configured by users in deployment. For that we use a config file, that is defining routes, title and more.

In this config file users can provide a title property for every route. This prop can be a LocaleMessageObject or a string. Objects are merged into the global locale-messages via i18n.mergeLocaleMessage with an auto generated path.

The title (document.title and toolbar-title) are calculated in a computed property. If the paths exists we output the localized title, otherwise the string (or nothing at all if its not a string or empty). For checking the existence of the path we use the te method.

sense-it-gmbh avatar Sep 17 '19 12:09 sense-it-gmbh

I am facing this problem as well, the solution above doesn't work for me...

yyywork avatar Jul 06 '22 09:07 yyywork

Because this.$root.$options.i18n.te(path, locale) messed up unit tests for me I went with a solution like this:

My translations are nested under another key like this

category: {
  provider: {
    a: 'Provider A',
    b: 'Provider B',
  },
},

and I fetch them like this

return this.$t(`category.provider.${provider}`)

so if the provider ends up being let's say c Vue i18n returns category.provider.c. Then instead of checking whether a translation exists at the given path with $te I just check whether the resulting text contains the translation keypath:

const translation = this.$t(`category.provider.${provider}`)
return translation.includes('category.provider.') ? 'fallback' : translation

omnichronous avatar Oct 03 '22 17:10 omnichronous