i18next / i18next-vue

Internationalization for Vue 2 & 3 using the i18next ecosystem

Home Page:https://i18next.github.io/i18next-vue/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Limit the scope of a SFC component to some namespace and key prefix.

YehorPytomets opened this issue · comments

🚀 Feature Proposal

Hello!

We propose to implement the possibility of narrowing down the scope of a t() function returned from the useTranslation() to a certain namespace and/or key prefix as this is possible with $t() function in a template.

Motivation

This will allow restricting the component to a certain subtree of localization terms that we defined specifically for this component and produce less code. As of now, we have to write similar full keys in each t() call:

<script setup>
    // imports...
    
    const {t} = useTranslation();
    const term1 = computed(() => t('namespace1:long.path.to.term1'));
    const term2 = computed(() => t('namespace1:long.path.to.term2'));
    // ...
    const termN = computed(() => t('namespace1:long.path.to.termN'));
</script>

Example

We propose reimplementing the useTranslation() to accept the i18nOptions that limit the returned t() function to the provided namespace and/or key prefix:

<script setup>
    // imports...
    
    const {t} = useTranslation({
        namepsaces: 'namespace1',
        keyPrefix: 'long.path.to',
    });
    const term1 = computed(() => t('term1'));
    const term2 = computed(() => t('term2'));
    // ...
    const termN = computed(() => t('termN'));
</script>

By the way, when applying i18nOptions to a component with Options API, the options apply only to the $t() function in a template:

<template>
<!-- Works as expected:  -->
<p>{{$t('term1')}}</p>
<!-- Still have to specify the full path:  -->
<p>{{term2}}</p>
<p>{{t('namespace1:long.path.to.term3')}}</p>
</template>

<script>
export default {
    i18nOptions: {
        namepsaces: 'namespace1',
        keyPrefix: 'long.path.to',
    },
};
</script>

<script setup>
    // imports...
    
    const {t} = useTranslation();
    const term2 = computed(() => t('namespace1:long.path.to.term2'));
</script>

Would be grateful to hear any feedback on that.

Your Environment

  • i18next: ^21.8.10
  • i18next-vue: 2.0.0-beta.0
  • vue: ^3.2.37
  • npm: 8.5.5
  • node: v16.15.0
  • browsers: Firefox, Chrome
  • os: Mac
  • run command: npm run serve

Would be great if this stays somewhat alined to react-i18next implementation so it's easy to switch from react-i18next to vue-i18next:

Yes, this sounds good. I'd like to take some time to look into this and experiment, so we get an API that feels right (any ideally is compatible with react-i18next).

In the new 2.0.0-beta.2 release i18nOptions will now be taken into account for the t retrieved via useTranslation().

This is a little more verbose than directly supporting it in useTranslation(), but it might work as an interim solution.

commented

Is the t function supposed to be limited by the component's i18nOptions?
I'm using the function inside a computed property but the ns is not limited until after the onMounted and the computed property is not being updated.

Hi @EranClientside,

yes, it should use i18nOptions. I included a working example below. If this does not help/not work in your setup, please open a separate issue so we can look into this.

<template>
  <h1>Issue 7b</h1>
  <p>computed: {{ term }}</p>
  <p>computed2: {{ otherTerm }}</p>
  <p>too early: {{ notLikeThis }}</p>
</template>


<script setup>
import { computed } from "vue";
import { useTranslation } from "i18next-vue";

const { t } = useTranslation();
const term = computed(() => t("some.key"));
// this is too early, because i18nOptions is only taking effect in `beforeCreate`, which runs after `setup`:
const notLikeThis = t("some.key"); 
</script>

<script>
export default {
  computed:{
    otherTerm(){
      return this.t("some.key");
    }
  },
  i18nOptions: {
    namespaces: "namespace1",
  },
  name: "issue-seven",
};
</script>

We plan to include this in i18next-vue v3. In fact, you can try it in the alpha version already: https://github.com/i18next/i18next-vue/releases/tag/v3.0.0-alpha.0

The syntax is

  const {t} = useTranslation('namespace1', {
    keyPrefix: 'long.path.to',
  });

See #16 for other changes planned for version 3.

As outlined above, this is implemented in v3.