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.
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.