intlify / vue-i18n-next Goto Github PK
View Code? Open in Web Editor NEWVue I18n for Vue 3
Home Page: https://vue-i18n.intlify.dev/
License: MIT License
Vue I18n for Vue 3
Home Page: https://vue-i18n.intlify.dev/
License: MIT License
Messages won't update, if the language changes, as soon as they are rendered inside of a component slot. This happens with both APIs. When using the i18n-t
component, a warning will appear in the console, but the behavior is the same as the function call, the message won't update.
[vue-i18n] Not found parent composer. use the global composer.
Legacy global scope example updated with slot
https://gist.github.com/hdahlheim/cc3f74474f8040bbe7d68cd29fb7f639
Place any $t()
/t()
calls or i18n-t
components inside the slot of a custom component and change the language.
The message inside of the slot updates.
The message stays the same as on the first render.
"vue": "3.0.2",
"vue-i18n": "9.0.0-beta.6"
"@intlify/vue-i18n-loader": "2.0.0-beta.1",
"@vue/cli": "4.5.8",
Add useI18n() without any options to a component
// This will set useScope=global
setup() {
return useI18n()
},
The component still uses local scope, since that way localization strings added by the vue loader can be used.
The component uses global scope. More confusing: if you add any option (e.g. the locale), the component will use local scope.
return useI18n({
useScope: 'local',
})
"vue": "^3.0.2",
"vue-i18n": "^9.0.0-beta.6",
"@intlify/vue-i18n-loader": "^2.0.0-beta.1",
as mentioned here - https://kazupon.github.io/vue-i18n/guide/locale.html
methods: {
changeLanguage: function (language) {
this.$root.$i18n.locale = language;
},
},
all messages should change to selected local
doesn't change
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@secretlint/secretlint-rule-preset-recommend
, secretlint
).github/workflows/ci.yml
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
actions/cache v4
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
actions/cache v4
actions/cache v4
actions/checkout v4
actions/setup-node v4
actions/cache v4
actions/upload-artifact v4
.github/workflows/github-label-sync.yml
r7kamura/github-label-sync-action v0
.github/workflows/release.yml
actions/checkout v4
actions/setup-node v4
jungwinter/split v2
stefanzweifel/git-auto-commit-action v5
.github/workflows/reproduire.yml
actions/checkout v4
Hebilicious/reproduire v0.0.9@4b686ae9cbb72dad60f001d278b6e3b2ce40a9ac
package.json
@eslint/js ^8.57.0
@rollup/plugin-commonjs ^25.0.0
@rollup/plugin-json ^6.0.0
@rollup/plugin-node-resolve ^15.0.2
@rollup/plugin-replace ^5.0.2
@rollup/plugin-terser ^0.4.3
@secretlint/secretlint-rule-preset-recommend ^3.1.0
@textlint-rule/textlint-rule-no-unmatched-pair ^2.0.0
@types/brotli ^1.3.4
@types/eslint ^8.56.7
@types/js-yaml ^4.0.5
@types/jsdom ^21.1.1
@types/minimist ^1.2.5
@types/node ^20.11.21
@types/rc ^1.2.4
@vitest/coverage-v8 ^1.3.0
api-docs-gen ^0.4.0
benchmark ^2.1.4
brotli ^1.3.2
bumpp ^9.3.0
cross-env ^7.0.3
esbuild-register ^3.5.0
eslint ^9.1.0
eslint-config-prettier ^9.1.0
eslint-plugin-vue ^9.25.0
execa ^5.0.0
fixpack ^4.0.0
globals ^15.0.0
globby ^14.0.1
jiti ^1.21.0
js-yaml ^4.1.0
jsdom ^24.0.0
lint-staged ^15.2.2
listhen ^1.7.2
minimist ^1.2.6
mlly ^1.6.1
npm-run-all2 ^6.1.2
opener ^1.5.2
pathe ^1.1.2
picocolors ^1.0.0
playwright ^1.34.0
prettier ^3.2.5
rc ^1.2.8
rimraf ^5.0.5
rollup ^3.29.2
rollup-plugin-node-builtins ^2.1.2
rollup-plugin-node-globals ^1.4.0
rollup-plugin-typescript2 ^0.36.0
secretlint ^3.2.0
serve-static ^1.15.0
textlint ^12.6.1
textlint-filter-rule-comments ^1.2.2
textlint-rule-abbr-within-parentheses ^1.0.2
textlint-rule-apostrophe ^2.0.0
textlint-rule-common-misspellings ^1.0.1
textlint-rule-diacritics ^1.0.0
textlint-rule-en-capitalization ^2.0.3
textlint-rule-max-comma ^4.0.0
textlint-rule-max-doc-width ^1.4.0
textlint-rule-no-empty-section ^1.1.0
textlint-rule-no-start-duplicated-conjunction ^2.0.2
textlint-rule-no-surrogate-pair ^1.0.1
textlint-rule-period-in-list-item ^1.0.0
textlint-rule-stop-words ^4.0.0
textlint-rule-terminology ^4.0.0
textlint-rule-unexpanded-acronym ^1.2.4
textlint-rule-write-good ^2.0.0
trash-cli ^5.0.0
tslib ^2.6.2
typescript ^5.3.3
typescript-eslint ^7.5.0
vitepress 1.1.4
vitest ^1.3.0
vue 3.4.27
typescript ^5.0.4
node >= 18
vue 3.4.27
vite ^5.1.2
packages/core-base/package.json
node >= 16
packages/core/package.json
node >= 16
packages/devtools-types/package.json
node >= 16
packages/format-explorer/package.json
vue ^3.3.4
source-map-js ^1.0.2
monaco-editor ^0.48.0
@vitejs/plugin-vue ^5.0.0
@vue/compiler-sfc ^3.3.4
vite ^5.1.4
vue-tsc ^2.0.0
packages/message-compiler/package.json
source-map-js ^1.0.2
node >= 16
packages/petite-vue-i18n/package.json
@vue/devtools-api ^6.5.0
vue ^3.0.0
node >= 16
packages/shared/package.json
node >= 16
packages/size-check-core/package.json
vite ^5.1.4
packages/size-check-petite-vue-i18n/package.json
vue ^3.3.4
@vitejs/plugin-vue ^5.0.0
@vue/compiler-sfc ^3.3.4
vite ^5.1.4
vue-tsc ^2.0.0
packages/size-check-vue-i18n/package.json
vue ^3.3.4
@vitejs/plugin-vue ^5.0.0
@vue/compiler-sfc ^3.3.4
vite ^5.1.4
vue-tsc ^2.0.0
packages/vue-i18n-core/package.json
@vue/devtools-api ^6.5.0
vue ^3.0.0
node >= 16
packages/vue-i18n/package.json
@vue/devtools-api ^6.5.0
vue ^3.0.0
node >= 16
I was looking for i18n in vue-next and had a look at vue-i18n-next. But to be honest it doesn't look very flexible, and it left me in confusion. I doubt if it is usable at all for me.
Vue-i18n-next seems just a static bucket of translations. You create it once, provide it a list of messages and then use it everywhere. But..
It does not make sense to me that you declare all messages in one place anyway.
Apps are usually divided into a component hierarchy. Components are meant to be independent. That's why nowadays you specify CSS within your vue SFC file. It makes sense to specify your translations within the component as well. And just like CSS inherits from the parent, it would be nice to inherit translations from the parent as well. It would be annoying to have to redeclare certain translations over and over within your app. And this pattern should allow you to override a translation in a sub component when needed. Maybe it should also support overriding translations of a reusable component by the parent.
I don't see any example covering this, and the library doesn't seem to allow chaining messages or date/number formats or something like it. Am I missing something?
ex:
cexbrayat/vue-cli-playground#2
yarn
and yarn serve
throws:
TS2345: Argument of type 'I18n<{ en: { hello: string; }; }, unknown, unknown, true>' is not assignable to parameter of type 'Plugin_2'.
Property 'install' is missing in type 'I18n<{ en: { hello: string; }; }, unknown, unknown, true>' but required in type '{ install: PluginInstallFunction; }'.
4 |
5 | createApp(App)
> 6 | .use(i18n)
| ^^^^
7 | .mount('#app')
Unit tests also fail.
It appears that the I18n
interface used to have an install
property, but no longer has one in beta.11.
We should be able to use the i18n plugin with TS
We can't use the plugin as it does not compile with beta.11
Could there be an example for loading messages asynchronously?
I've made logic for that, but am still debugging why my code is not working...
ex:
https://jsfiddle.net/x0o2cL67/
How to output 'xxx: { $100, $xxx }' string directly, some scenarios need to output special characters.
Output string with no error.
"vue-i18n": "^9.0.0-beta.10", "vue": "^3.0.4"
The error when using i18n-next globally - Uncaught (in promise) TypeError: _ctx.$t is not a function
This happened after I had done npm update today. All was working fine before. The only change was versions updating.
Thats how I plug in i18n:
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { createI18n } from 'vue-i18n'
import messageDictionary from '@/i18n/messageDictionary'
const i18n = createI18n({
legacy: false,
locale: 'ru',
fallbackLocale: 'ru',
availableLocales: ['ru', 'kz', 'en'],
messages: messageDictionary()
})
const app = createApp(App)
app.use(store)
app.use(i18n)
app.use(router).mount('#app')
Thats client code causing error:
client.vue
<template>
<h6 class="mb1">
{{ $t('land.new-land') }}
</h6>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
setup() {
return {}
}
})
</script>
Last package.json:
"dependencies": {
"@types/vuelidate": "^0.7.13",
"@vuelidate/core": "^2.0.0-alpha.8",
"@vuelidate/validators": "^2.0.0-alpha.5",
"axios": "^0.21.0",
"vue": "^3.0.4",
"vue-i18n": "^9.0.0-beta.10",
"vue-router": "^4.0.1",
"vuex": "^4.0.0-rc.2",
"xstate": "^4.15.1"
},
"devDependencies": {
"@types/jest": "^24.0.19",
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-eslint": "^4.5.9",
"@vue/cli-plugin-router": "^4.5.9",
"@vue/cli-plugin-typescript": "^4.5.9",
"@vue/cli-plugin-unit-jest": "^4.5.9",
"@vue/cli-plugin-vuex": "^4.5.9",
"@vue/cli-service": "^4.5.9",
"@vue/compiler-sfc": "^3.0.4",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^2.0.0-beta.12",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.2.0",
"eslint-plugin-vue": "^7.2.0",
"node-sass": "^4.12.0",
"prettier": "^1.19.1",
"sass-loader": "^8.0.2",
"typescript": "~3.9.3",
"vue-jest": "^5.0.0-alpha.7"
}
Previous package.json:
"dependencies": {
"@types/vuelidate": "^0.7.13",
"@vuelidate/core": "^2.0.0-alpha.8",
"@vuelidate/validators": "^2.0.0-alpha.5",
"axios": "^0.21.0",
"vue": "^3.0.3",
"vue-i18n": "^9.0.0-beta.8",
"vue-router": "^4.0.0-rc.5",
"vuex": "^4.0.0-rc.2",
"xstate": "^4.14.1"
},
"devDependencies": {
"@types/jest": "^24.0.19",
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-eslint": "^4.5.9",
"@vue/cli-plugin-router": "^4.5.9",
"@vue/cli-plugin-typescript": "^4.5.9",
"@vue/cli-plugin-unit-jest": "^4.5.9",
"@vue/cli-plugin-vuex": "^4.5.9",
"@vue/cli-service": "^4.5.9",
"@vue/compiler-sfc": "^3.0.3",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^2.0.0-beta.11",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-0",
"node-sass": "^4.12.0",
"prettier": "^1.19.1",
"sass-loader": "^8.0.2",
"typescript": "~3.9.3",
"vue-jest": "^5.0.0-alpha.6"
}
export const i18n = createI18n({
locale: 'zh-cn',
legacy: true,
....
[Vue warn]: beforeDestroy
has been renamed to beforeUnmount
.
ex:
<div class="text-subheadline min-w-24 h-8 text-left pl-2 leading-8">{{ t(`language.${menuItem.name}`) }}</div>
const i18n = useI18n()
i18n.locale = 'en' // change locale
Page text is changed as expected
Nothing is happen, but console.log(i18n.locale)
shows i18n.locale
has been changed successfully.
Hello,
pls how should works this new version with hot reloades?
I'm trying to utilize this example https://kazupon.github.io/vue-i18n/guide/hot-reload.html#advanced-example for new API, but
i18n.setLocaleMessage function do not propagate changed message into current view.
Migration of previously working state.
Cannot access translations in Vue components. I am using webpacker WITHOUT asset pipeline.
In Vue 2.X we were using dynamic definition of current locale in the header of our webpage (Ruby/Rails) which would dynamically pull in a file with JSON-formatted translation key-value pairs. When the user changed locale, a different localization file would be used for translations.
javascript
window.Locale = "#{I18n.locale}"; // 'en', 'de', etc...
window.LocaleData = {};
= javascript_include_tag "locales/#{I18n.locale}" // loads file with JSON translations
We used the following code to initialize the Vue app:
import Vue from 'vue/dist/vue.esm.js';
import VueI18n from 'vue-i18n';
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: window.Locale,
fallbackLocale: 'de'
});
const rawData = window.LocaleData.translations[window.Locale];
i18n.setLocaleMessage(window.Locale, rawData);
export default i18n;
I've created a basic vue app, generated JSON translation strings and initialized the vue app with vue-i18n:
import { createApp } from 'vue'
import { createI18n, useI18n } from 'vue-i18n'
import HelloWorld from '@/components/HelloWorld.vue'
const i18n = createI18n({
locale: window.Locale,
messages: {}
})
const messages = window.LocaleData.translations[window.Locale];
i18n.global.setLocaleMessage(window.Locale, messages);
export default () => {
document.addEventListener('DOMContentLoaded', () => {
const app = createApp(HelloWorld, {
setup() {
const { t, locale } = useI18n()
return { t, locale }
}
})
app.use(i18n)
app.mount('#vue-app')
})
}
However, if I access $t('translation.path.here')
or this.$t('translation.path.here')
in a component, the app is failing with:
TypeError: Cannot read property '$t' of undefined
$t
available first by importing it?$t
globally in all components - is the setup()
section in createApp
actually the right way to do it?$t
is available in all of them - globbing all components so they don't have to be imported by name one by oneCould you help with the migration? Many Rails/Go developers would need this for webapps where Vue is the frontend.
Thank you.
Hello, thank you for your work. I'm trying to use the vue-i18n-next
with vue 3
but it does not seem to work for nested components (or child component).
I tried codesandbox.io but there are some issues with vue 3 import, so here is the complete list of files to reproduce the issue.
In the App wrapper view, there is a i18n text which works and an other component Login
which also use i18n. But i18n only works for the wrapper container and not for the login view.
App.vue
<template>
{{t("login.title")}}
<br/>
does it works for login ?
<Login></Login>
</template>
<script>
import {useI18n} from "vue-i18n";
import Login from "./components/Accounts/Login";
export default {
name: 'App',
components: {
Login
},
setup() {
return useI18n()
}
}
</script>
<style>
</style>
Login.vue
<template>
<div>
{{ t("login.title") }}
</div>
</template>
<script>
export default {
name: 'Login',
components: {
}
}
</script>
<style lang="scss">
</style>
main.js
import {createApp} from 'vue'
import App from './App.vue'
import router from "./routes/routes";
import i18n from "./i18n";
const app = createApp(App);
app.use(router);
app.use(i18n);
app.mount('#app')
i18n.js
import {createI18n} from 'vue-i18n'
const i18n = createI18n({
locale: 'en',
globalInstall: true,
messages: {
en: {'login.title': 'test'}
}
})
export default i18n;
I expect to translate the key inside the login view also and nested children.
Only the translation inside App.vue
works, the translate for Login.vue
does not work.
As the code seems to import defineComponent and other props directly from the "vue" package, I was curious, if this is also usable with the Vue 2 composition-api plugin, as I couldn't find anything relating to that inside the docs till now. Thanks in advance for you time!
Looks like defineComputed
call is not needed because computed
is immediately unwrapped and only primitive string value is returned.
Line 505 in d0ed0a5
I have an e-mail address in a translation instruction that contains the @ sign.
My drawing instruction:
email: '[email protected]'
The call:
<p>{{ t('email') }}</p>
I expect it to be translated 1 to 1.
Error on the console is thrown. But Webpack can compile it. So the error will happen at runtime.
const i18n = createI18n({
messages: {
en: import('/path/to/en.json').default
}
}
const i18n = useI18n({
messages: {
en: import('/path/to/en.json').default
}
}
On Beta 4 i get on a page change with [email protected] an error
vueI18n.__disableEmitter && _vueI18n.__disableEmitter();
it related to
_vueI18n.__disableEmitter && _vueI18n.__disableEmitter();
On Beta 3 everything works fine
Hello @kazupon ! I'm trying out vue-i18n with Vitedge, which is doing SSR using Vite. It works well when running in a Node.js server.
However, it crashes when running in a Cloudflare Worker environment. I'm not providing a repro link since you would need a Cloudflare account and all of that, but I'm giving more info in the following.
ex:
Use vue-i18n
in any Vue app running on a Cloudflare Worker (SSR, different from Node.js environment).
It should work.
It crashes with error Code generation from strings disallowed for this context
when the t
function is called. This error means that eval
and related unsafe calls are not allowed in this environment.
After researching for a while, I found that the line that makes it crash is here: https://github.com/intlify/vue-i18n-next/blob/master/src/message/compiler.ts#L73
This new Function('...')
is basically a different form of eval
, and such a thing is forbidden in a worker environment due to security reasons.
Do you think this could be implemented in a different way without relying on eval
? Or any other workaround to support this environment?
Thank you!
ex:
Hi, is it possible to use vue-i18n outside of regular vue components? I'm trying to set the document title inside my router file.
What I tried so far is to import "useI18n" and pass the same options I used to call "createI18n". Like this:
import { useI18n } from 'vue-i18n'
import { i18nOptions } from '@/plugins/i18n'
const { t } = useI18n(i18nOptions)
All I got so far where "createCompileError/createI18nError"
Thank you for your work and help :)
Is it intended behavior that you can't use dot seperated keys for the translation messages anymore?
In the previous version for Vue 2, I often declared messages like this:
{
"side": "Side",
"side.left": "Left",
"side.right": "Right"
}
which does not work anymore.
code
import { createI18n, LocaleMessages } from 'vue-i18n'
function loadLocaleMessages (): LocaleMessages {
const locales = require.context('./locales', true, /[A-Za-z0-9-,\s]+.json$/i)
const messages: LocaleMessages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-]+)./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key)
}
})
return messages
}
const i18n = createI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})
export default i18n;
error
Type 'Record<string, LocaleMessageDictionary>' is not assignable to type 'Record<string, LocaleMessageDictionary>'.
Index signatures are incompatible.
Type 'LocaleMessageDictionary' is not assignable to type 'LocaleMessageDictionary'.
20 | locale: process.env.VUE_APP_I18N_LOCALE || 'en',
21 | fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
22 | messages: loadLocaleMessages()
| ^^^^^^^^
23 |
24 | })
While I agree that using t() and d() and so on as helpers is useful, most of the properties added by useI18n are not required to be directly on the component. Especially, since they may clash with other properties and cause unexpected behavior when new ones are added later.
Those methods should be fine (people using single letter variables can be punished π):
d
n
t
tm
I suggest to move all those properties to a new i18n wrapper object, so that they need to be accessed using this.i18n.availableLocales
:
availableLocales:Array[4]
datetimeFormats:Object (Computed)
escapeParameter:false
fallbackFormat:false
fallbackLocale:"en" (Computed)
fallbackRoot:true
fallbackWarn:true
getDateTimeFormat:Ζ getDateTimeFormat(locale)
getLocaleMessage:Ζ getLocaleMessage(locale)
getMissingHandler:Ζ getMissingHandler()
getNumberFormat:Ζ getNumberFormat(locale)
getPostTranslationHandler:Ζ getPostTranslationHandler()
id:3
inheritLocale:true
isGlobal:false
locale:"de" (Computed)
mergeDateTimeFormat:Ζ mergeDateTimeFormat(locale, format)
mergeLocaleMessage:Ζ mergeLocaleMessage(locale, message)
mergeNumberFormat:Ζ mergeNumberFormat(locale, format)
messages:Object (Computed)
missingWarn:true
modifiers:Object (empty)
numberFormats:Object (Computed)
pluralRules:undefined
setDateTimeFormat:Ζ setDateTimeFormat(locale, format)
setLocaleMessage:Ζ setLocaleMessage(locale, message)
setMissingHandler:Ζ setMissingHandler(handler)
setNumberFormat:Ζ setNumberFormat(locale, format)
setPostTranslationHandler:Ζ setPostTranslationHandler(handler)
warnHtmlMessage: true
"vue": "3.0.2",
"vue-i18n": "9.0.0-beta.6"
"@intlify/vue-i18n-loader": "2.0.0-beta.1",
"@vue/cli": "4.5.8",
Add vue-i18n dependencies. In your component, include:
setup() {
return useI18n()
},
Do not include any global config in your main app (no createI18n
)
An error indicating what happened and suggesting a solution to fix this.
The console says "unexpected error"
This is caused by:
throw createI18nError(15);
In this case, a more descriptive error message should be printed.
In Vue3 it is possible to globally install instance methods such as $t
with app.config.globalProperties
, is that already supported or is support coming?
@kazupon made an example for implementing locale string as the root route param i.e. /en/home
: a7d2147
Which gave me an idea of opening a feature request and discussion about this specific need, which in my mind would seem a great enhancement and a quite possibly real need for some projects.
How can we localize full route paths? Like /en/home
-> /sv/hem
?
Is there actually need for this, or would there be some downsize like with SEO? Perhaps some webstores would find it especially useful to be able to localize their product page urls?
Are there some ready solutions for this already? Could or should it be a feature with this library?
How to actually implement this?
After switching languages
After switching languages, the fields selected in the drop-down box are not changed to the corresponding language
After switching languages, the field selected in the drop-down box is changed to the corresponding language
ps:
Did I use it wrong? thank you
Install package with npm as a dependency -> check dist files of package in node_modules.
All "internal" files to the package should logically be included when installing it.
The module @intlify/core/src/runtime
does not seem to be included in the published package. The package simply seems to try loading files from outside the dist folder which isn't part of the published package. This is at least an issue when using Typescript.
The following snippet is from the types file of the published package. Note all the imports from the core/src folder.
import type { App } from 'vue';
import type { ComponentInternalInstance } from 'vue';
import type { ComputedRef } from '@vue/reactivity';
import type { DateTimeFormat } from '@intlify/core/src/runtime';
import type { DateTimeFormats } from '@intlify/core/src/runtime';
import { DateTimeOptions } from '@intlify/core/src/runtime';
import type { FallbackLocale } from '@intlify/core/src/runtime';
import { LinkedModifiers } from '@intlify/runtime';
import type { Locale } from '@intlify/core/src/runtime';
import type { LocaleMessageDictionary } from '@intlify/core/src/runtime';
import type { LocaleMessages } from '@intlify/core/src/runtime';
import type { LocaleMessageValue } from '@intlify/core/src/runtime';
import { MessageFunction } from '@intlify/runtime';
import { MessageFunctions } from '@intlify/runtime';
import type { NamedValue } from '@intlify/runtime';
import type { NumberFormat as NumberFormat_2 } from '@intlify/core/src/runtime';
import type { NumberFormats } from '@intlify/core/src/runtime';
import { NumberOptions } from '@intlify/core/src/runtime';
import type { ObjectDirective } from 'vue';
import { Path } from '@intlify/message-resolver';
import { PathValue } from '@intlify/message-resolver';
import { PluralizationRule } from '@intlify/runtime';
import type { PluralizationRules } from '@intlify/runtime';
import { PostTranslationHandler } from '@intlify/core/src/runtime';
import type { RenderFunction } from 'vue';
import type { SetupContext } from 'vue';
import { TranslateOptions } from '@intlify/core/src/runtime';
import type { VNode } from 'vue';
import type { WritableComputedRef } from '@vue/reactivity';
π We just released @formatjs/intl
that detaches the imperative API from the React binding (react-intl uses this basically) so I'm curious if vue-i18n-next can use it? It basically has everything that react-intl supports (custom formats, default timeZone, format merging, handling AST vs regular messages).
I'm curious what the roadmap for vue-i18n-next is as well?
No hard feelings if this doesn't happen π
vue: 3.0.0-rc.5
Trying npm install --save vue-i18n@next
command, it installs 9.0.0-alpha.1 instead of 9.0.0-alpha.13.
When I do:
"vue-i18n": "^9.0.0-alpha.13",
npm update
import { useI18n } from 'vue-i18n'
anymore and asks me to install vue-i18n package although it is already installed (I mean alpha version)How can I fix it?
Thank you in advance.
vue-18n: v9.0.0.-alpha.11
vue: 3.0.0-rc.5
I use dayjs and i should return my string similar to this:
messages: {
en: {
time: {
future: 'in %s',
}
}
}
I call t() in setup() function:
import { useI18n } from 'vue-i18n'
setup () {
const { t, locale } = useI18n()
console.log( t('time.future') )
}
However, it returns "in s" instead of "in %s".
I am not sure if it is a bug or a feature. How can we fix this?
https://codesandbox.io/s/stupefied-nightingale-5kv28?file=/src/App.vue
When using the functional components (no matter if with or without named slots), a warning comes up in the application stating "[vue-i18n] Not found parent composer. use the global composer.". Now I'm not quiet sure if this is something that should be fixed or if it's something to be expected and if so, why does this warning shows up?
Hi!
I think there was an error in the publication of the version 9.0.0-beta.3
, it was published on the latest
tag!
https://codepen.io/pgbross/pen/YzWLBYy
Create i18n with missing key handler
Translate missing key
Observe response string is the key not the output of the missing key handler.
The output of the missing handler to be returned.
Translate key with no message and missing handler defined, the key is returned as the translation.
Greetings,
Thanks a lot for your work!
VueI18n is using some object spread operations which are not converted to <ES2018.
The final product (node_module dist build) might want to take into consideration to target older versions (not supporting object spread) as well.
This can be for Example found in
and other places.
Thanks a lot for reaching out and if there is something I can do to fix this, might be a babel config I am forgetting, please let me know
Hi authors and new authors of vue-i18n
In the use cases of ours. We are expanding our i18n to around 50+ languages. Some of the UI strings for i18n are very short, such as button labels (e.g. "Go", "Next", etc, very short and can be interpreted in many ways). We will need to provide some addition context for the translators to understand what the UI strings means. I check the vue-i18n and it seems it only has key-value format. Does it provide anyway to give additional explanatory descriptions? I know we can provide in comments. But comments in both json
or yml
are not standardized and normally not supported in tooling for reading. We need to send our translation requests to other 3rd-party translation tools so it's better that the input source file of vue-i18n allow official way to specify description.
Such additional information can also include author of each string / unique identifying Id / timestamps etc. Examples are
Until vue-i18n , we might use the .vscode/i18n-ally-reviews.yml
which contains description
for i18n strings. We are happy that an organization intlify
will support vue-i18n from now on and I wonder if such metadata will be standardized and included in future roadmaps
Hi vue-i18n
authors,
I am working on Vue 3 project and trying to switch locale via URL i18n.locale=to.params.lang
. In the components where I am using ...useI18n()
inside the return of setup()
to retrievelocale
, but locale property does not change dynamically as expected.
Thanks!
"vue": "^3.0.4",
"vue-i18n": "^9.0.0-beta.12",
"@intlify/vue-i18n-loader": "^2.0.0-beta.2",
https://github.com/Alymbek/vue3-i18n-next
standard
should work
getting error message:
Syntax Error: TypeError: vue_i18n_1.friendlyJSONstringify is not a function
in this part of documentation we see :
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
const app = createApp({
// something options ...
})
app.use(i18n)
app.mount('#app')
where the i18n
instance is missing, the example should be like :
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
const app = createApp({
// something options ...
})
const i18n = createI18n({...})
app.use(i18n)
app.mount('#app')
vue: 3.0.0
vue-i18n: 9.0.0-beta.4
plugins/i18n.js
import { createI18n } from 'vue-i18n';
const i18n = new createI18n({
legacy: true,
locale: 'en',
messages: {}
});
/**
* @param {String} locale
*/
export async function loadMessages(locale) {
const messages = await import(/* webpackChunkName: "lang-[request]" */ `~/lang/${locale}`);
i18n.setLocaleMessage(locale, messages);
if (i18n.locale !== locale) {
i18n.locale = locale;
}
}
(async function () {
await loadMessages('en');
})();
export default i18n;
app.js
import { createApp } from 'vue';
import App from './App.vue';
import i18n from '~/plugins/i18n';
const app = createApp(App);
app.use(router)
.use(i18n)
.mount('#app');
App.vue
<template>
<div class="main-app">
{{ $t('home_page') }}
</div>
</template>
<script>
export default {
name: 'VueApp',
setup() {
}
};
</script>
ERROR MESSAGE
Unhandled Promise Rejection: TypeError: i18n.setLocaleMessage is not a function. (In 'i18n.setLocaleMessage(locale, messages)', 'i18n.setLocaleMessage' is undefined)
I use this frequently when defining content that is systematic.
For example when i have components that take objects, for instance, I have a FormControl component that takes an object of validationMessages
keyed to validation rules. I can rely on vue-i18n to store this object exactly as I want it with no need for tricky back and forth:
// i18n
form: {
firstNameInput:{
label: 'first name',
validationMessages: {
required: 'please enter a first name',
length: 'please ask your parents for a shorter name',
}
}
}
// component
<FormControl validation-messages="$t('form.firstNameInput.validationMessages)"/>
// or even
<FormControl v-bind="$t('form.firstNameInput)"/>
Or when I know something will be a list:
// i18n
cancellation: {
reasons: [`It was too big`, `It was too small`, `It looked a bit too much like a sailboat`, `it had a strange smell`]
}
// component
<ul>
<li v-for="reason in $t('cancellation.reasons')>{{ reason }}</li>
</ul>
This flexibility has been amazing for us, allowing us to rely on vue-i18n to store structured content that we can use programmatically (especially when defining form controls). I don't understand any benefit to ensuring objects don't come back. Is there a new function that can be used instead?
hi, dear comrades!
thank you for your great library.
I'm facing with isue with vue-i18 in single file usage:
[vue-i18n] Not found 'hello' key in 'en' locale messages
I just following standart steps from you official guide, but no luck.
see details below:
dependencies:
"vue": "^3.0.2", "vue-i18n": "^9.0.0-beta.6",
devDependencies:
"@intlify/vue-i18n-loader": "^2.0.0-beta.1", "vue-loader": "^16.0.0-beta.9",
main.js:
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import { createI18n } from "vue-i18n";
// setup i18n instance with globaly
const i18n = createI18n({
legacy: false,
locale: "en",
messages: {
en: {
// ...
},
ja: {
// ...
},
},
});
createApp(App).use(store).use(router).use(i18n).mount("#app");
about.vue:
.about h1 This is an about page - {{ $t('hello') }} { "en": { "hello": "hello world!" }, "ja": { "hello": "γγγ«γ‘γ―γδΈη!" } } `webpack.config.js:
module: {
rules: [
{
resourceQuery: /blockType=i18n/,
type: "javascript/auto",
loader: "@intlify/vue-i18n-loader",
},
]}
if use messages in main.js it is working.
also want to note that your rules should be before all of other rules, otherwise getting error:
Module build failed (from ./node_modules/@intlify/vue-i18n-loader/lib/index.js):
SyntaxError: Unexpected token < in JSON at position 0
The README file in this repo has some bad links - [404:NotFound]
Status code [404:NotFound] - Link: https://github.com/intlify/vue-i18n-next/blob/master/examples/legacy/composition/translation.html
Status code [404:NotFound] - Link: https://github.com/intlify/vue-i18n-next/blob/master/examples/legacy/compostion/datetime-format.html
Status code [404:NotFound] - Link: https://github.com/intlify/vue-i18n-next/blob/master/docs/vue-i18n.md
This was found by an new experimental hobby project that I have just created: https://github.com/MrCull/GitHub-Repo-ReadMe-Dead-Link-Finder
If this has been in any way helpful then please consider giving the above Repo a Star.
p.s. the link given in the Issue template is also bad:
I created a basic example with Vue3 and vue-i18n-next (^9.0.0-beta.10
) I followed the instruction and I reviewed the example date-time file but in any case I'm no able to display the date in my view with the d
function. I just return this message:
Not found 'short' key in 'en' locale messages.
I don't know what I'm doing wrong or maybe it's an issue. The main files are (the repo here):
main.ts
const i18n = createI18n({
legacy: false,
dateTimeFormats: {
en: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric',
},
long: {
year: 'numeric',
month: 'short',
day: 'numeric',
weekday: 'short',
hour: 'numeric',
minute: 'numeric',
},
},
},
locale: 'en',
fallbackLocale: 'en',
messages: {
en: {
message: {
hello: 'hello world',
},
},
},
});
createApp(App)
.use(router)
.use(i18n)
.mount('#app')
Vue file
<h1>
Current time: "{{ d(new Date(), 'short') }}"
</h1>
...
<script lang="ts">
export default defineComponent({
name: 'App',
setup() {
const { d } = useI18n();
return {
d,
};
},
});
</script>
Need manual/guide to make/configure the production build.
Or disable that warning message in Console.
showing message in Console:
You are running a development build of vue-i18n.
Make sure to use the production build (*.prod.js) when deploying for production.
is it possible to dynamically change language?
I would like to press a button to toggle the language between english and swedish for example
how can i do it?
Vue 3 has this yet experimental syntax Script Setup 'SFC Composition API Syntax Sugar'.
I'm wondering how to best expose the translation method t
in components written with this syntax.
Currently this syntax is working for me:
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
export const name = 'ViewName';
// Note: vue-meta package does not support Vue 3 as of yet, but am verifying functionality
// by being able to use this object in template syntax.
export const metaInfo = {
title: t('PAGE_TITLE'),
meta: [
{ name: 'description', content: t('PAGE_DESCRIPTION') },
],
};
</script>
<template>
<h1>{{ metaInfo.title }}</h1>
</template>
However, I would like to be able to write it like this:
<script setup lang="ts">
export const name = 'ViewName';
export const metaInfo = {
title: $t('PAGE_TITLE'),
meta: [
{ name: 'description', content: $t('PAGE_DESCRIPTION') },
],
};
</script>
Would it be possible for this library to automatically expose $t method in script setup scope? Or by object-destructuring from setup context <script setup="_, { $t }" lang="ts">
?
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.