i18next / i18next-vue Goto Github PK
View Code? Open in Web Editor NEWInternationalization for Vue 2 & 3 using the i18next ecosystem
Home Page: https://i18next.github.io/i18next-vue/
License: MIT License
Internationalization for Vue 2 & 3 using the i18next ecosystem
Home Page: https://i18next.github.io/i18next-vue/
License: MIT License
Since this repository has been migrated, the GitHub workflows contained in it need to be updated to match the new organization information.
Thank you so much for the clear migration documentation it has mostly been a beeze to migrate from @panter/vue-i18next.
I've discovered a couple of slightly unexpected behaviors.
<i18next>
component is deprecated. However, it seems it was added in V1 hereTranslationComponent
doesn't seem to be working as expected -- the child value isn't interpolated. This seemingly is because the translation prop enters the component's render
function with the template values stripped (see screenshot)This is a private repository so I unfortunately cannot provide a reproduction but below is my i18next config:
import i18next from 'i18next';
import I18NextVue from 'i18next-vue';
import Vue from 'vue';
import english from '../locales/en/translation.json';
import spanish from '../locales/es/translation.json';
i18next.init({
lng: 'en',
nsSeparator: false,
keySeparator: false,
fallbackLng: false,
resources: {
en: { translation: english },
es: { translation: spanish },
},
interpolation: {
prefix: '{',
suffix: '}',
},
});
Vue.use(I18NextVue, { i18next });
export function setDefaultInterpolationVariables(variables: { [key: string]: string }) {
i18next.options.interpolation!.defaultVariables = variables;
}
The following snippet
<i18next :translation="$t('Need help with {processor}?')">
<template #processor>{{ processor }}</template>
</i18next>
with the follow es
translation file key/value pair
"Need help with {processor}?": "ΒΏNecesita ayuda con {processor}?",
Is it able to support v-t directive
I think v-t directive can make code more flexible, since we can provide a default transaction from the code
<p v-t="helloworld">Hello world</p>
In a fresh nuxt 3 app, if you add a util function, and import i18next-vue
in a component, then type checking breaks for the util function.
It's possible this is more of a nuxt issue, but i thought i would report it here first since adding/removing this specific import causes/fixes the issue.
Here's a minimal reproduction: https://stackblitz.com/edit/github-zn8swb?file=package.json&terminal=typecheck
If you run npm run typecheck
in the stackblitz console, you will get errors. If you comment out the import of i18next-vue
then typechecking passes.
Should not cause typescript issues
Unable to install using npm and install from zip / folder creates unexpected errors
For the module to be installed
NPM throws a 404 error message
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.
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>
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.
Hi, thank you for the awesome framework, it's so amazing!
I have two question:
Type instantiation is excessively deep and possibly infinite
while using useTranslation
composable function in a Vue component. I've searched some similar issues but did not find the solution.https://stackblitz.com/edit/github-lup5wg?file=src%2Fcomponents%2FComponentTypeError.ts
Both useTranslation()
and t()
has the type error:
import { h, computed } from 'vue';
import { useTranslation } from 'i18next-vue';
export default {
name: 'ComponentTypeError',
setup() {
// Here is the type error
const { t } = useTranslation();
// Here is the type error
const insurance = computed(() => t('insurance'));
return () => {
return h('div', `inline => ${insurance.value}`);
};
},
};
Hello!
When using i18next
object returned from the useTranslation()
in computed properties to get the current language, for example in a language switcher component, we expect it to be reactive as docs in the index.ts specify. But it it isn't.
For example, in the following component, neither of the computed properties will be updated after the language change:
<template>
<p>firstLanguage: {{firstLanguage}}</p>
<p>resolvedLanguage: {{resolvedLanguage}}</p>
<p>language: {{language}}</p>
<button @click="translateToChinese">Zh</button>
<button @click="translateToEnglish">En</button>
</template>
<script setup>
import {computed} from 'vue';
import {useTranslation} from 'i18next-vue';
const {i18next} = useTranslation();
const firstLanguage = computed(() => i18next.languages[0]);
const resolvedLanguage = computed(() => i18next.resolvedLanguage);
const language = computed(() => i18next.language);
function translateToChinese() {
i18next.changeLanguage('zh');
}
function translateToEnglish() {
i18next.changeLanguage('en');
}
</script>
But the t()
function updates as expected. To temporary work around this issue we've created our local composable that makes the i18next
reactive by subscribing to common i18next events:
import {readonly, shallowRef, triggerRef} from "vue";
import {useTranslation} from "i18next-vue";
/**
* Composable that makes the `i18next` object reactive, allowing to trigger language updates.
*
* <p>Exposes the `t()` function and `i18next` object from the `useTranslation()` composable,
* but with reactive `i18next`.
*/
export default function useI18next() {
const {i18next: i18nextOriginal, t} = useTranslation();
const i18next = shallowRef(i18nextOriginal);
// watch for common i18next events: https://www.i18next.com/overview/api#events
i18nextOriginal.on("languageChanged", update);
i18nextOriginal.on("loaded", update);
i18nextOriginal.store.on("added", update);
i18nextOriginal.store.on("removed", update);
function update() {
triggerRef(i18next); // trigger update
}
return {
i18next: readonly(i18next), // prohibits changing `i18next` value in components
t,
}
}
Could you please fix that and make the i18next
returned from useTranslation()
reactive, or clarify why it is not reactive if it is so by design and describe this in the documentation explicitly. Because the composable name makes us believe that the returned values are reactive, if not stated the opposite. Hope our solution helps in some way.
I would be grateful to get any feedback on that.
It is expected that the i18next
is reactive and can be used in computed properties to get the current language.
A clear and concise description of what the feature is.
Please outline the motivation for the proposal.
Please provide an example for how this feature would be used.
Hello! in index.ts
have some error when using i18next >= v22.5.0
When i want used i18next-resources-to-backend , lang loaded after render component. How change it. I need lang load before render
i18n.use(resourcesToBackend((language: string) => import(`./locales/${language}.json`))).init({
detection: {
order: ['cookie', 'localStorage'],
lookupCookie: 'slang',
lookupLocalStorage: 'last_language',
},
fallbackLng: getDefaultLanguage(),
debug: true,
});
debug info
render App
i18next.js:13 i18next::backendConnector: loaded namespace translation for language uk {qwe: 'uk', order: {β¦}, basicSkeleton: {β¦}, cardForm: {β¦}, form: {β¦},Β β¦}
i18next.js:13 i18next: languageChanged uk
i18next.js:13 i18next: initialized {debug: true, initImmediate: true, ns: Array(1), defaultNS: Array(1), fallbackLng: Array(1),Β β¦}
how fix it?
when i'm changeLanguage in router.beforeEach -> in template i have old $i18next.language value
We propose to implement the <i18next>
that was available in @panter/vue-i18next and and made it much easier to insert HTML and components as interpolation values.
Now we have to write HTML snippets outside of a template in a <script>
and cannot use components as interpolation values.
For example, the following case with <i18next>
component was rewritten into a composable that encapsulates translation and interpolation details:
<!--
- Vue 2
- @panter/vue-i18next
-->
<template>
<!-- ...some other template code... -->
<i18next tag="p" class="value" path="license.goToTermsOfUse">
<router-link :to="{ name: 'LICENSE' }"
class="link"
place="termsOfUse">
{{ $t('license.termsOfUse') }}
</router-link>
</i18next>
</template>
<!--
- Vue 3
- i18next/i18next-vue
-->
<template>
<!-- ...some other template code... -->
<p class="value" v-html="goToTermsOfUse"/>
</template>
<script setup>
// imports and other code...
const {t} = useTranslation();
const {goToTermsOfUse} = useTermsOfUse(t);
/** Creates and exposes localized message of Terms of use. */
function useTermsOfUse(t) {
const router = useRouter();
const termsOfUseLink = router.resolve({ name: 'LICENSE' }).href;
const termsOfUse = computed(() => t('somenamespace:license.termsOfUse'));
const goToTermsOfUse = computed(() => t('somenamespace:license.goToTermsOfUse', {
termsOfUse: `<a class="link" href="${termsOfUseLink}">${termsOfUse.value}</a>`,
interpolation: {escapeValue: false},
}));
return {
goToTermsOfUse,
};
}
</script>
Both of the snippets render the following message:
I would be grateful to hear any response on the possibility of implementing that component.
A clear and concise description of what the bug is.
A minimal reproducible example.
A codesandbox example or similar
or at least steps to reproduce the behavior:
// Paste your code here
A clear and concise description of what you expected to happen.
// Paste the expected results here
i18next-vue
v3For version 3, we'd like to streamline the API of i18next-vue
and lean more on the Composition API. Please leave your feedback below.
We have released version 3.0.0 and a migration guide with the (breaking) changes.
You are still welcome to leave a comment below.
i18next
>=23useTranslation()
with parameters to specify a fixed language, namespace(s) and a keyprefix (all optional)
i18nOptions
in the Options API
useTranslation()
for most of these use-casesmessages
behind a legacy flag until v4.<i18n>
blocks in SFCs
@intlify/unplugin-vue-i18n
produce a different, function-based format now, which is not what we wanti18nOptions
and <i18n>
useTranslation()
These are all quite big changes if you are relying on them in an existing application. That's why we are looking for your user feedback in this issue as a comment below.
Let us know, which feature you would like to keep, or where you would like some backward compatibility to ease the upgrade process to v3. All of the changes are still up for debate.
Thank you!
Ref:
When I use i18next react, it supports TypeScript. Could this vue version also add TypeScript support for the $t interface?
https://react.i18next.com/latest/typescript
Add translation key validation/auto-completion support during dev.
//similar usage as react version.
const { t } = useTranslation('settings')//namespace support, load namespace if it's not loaded
t('TranslationKey')//can be validated by TypeScript
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.