Git Product home page Git Product logo

vue-i18n-next's Introduction

vue-i18n-next

This is the repository for Vue I18n 9 for Vue 3

Internationalization plugin for Vue.js

Supporting Vue I18n & Intlify Project

Vue I18n is part of the Vue Ecosystem and Intlify Project is an open source project with its ongoing development made possible entirely by the support of Sponsors. If you would like to become a sponsor, please consider:

๐Ÿ… Platinum Sponsors

โœจ Special Sponsors

๐Ÿฅ‡ Gold Sponsors

๐Ÿฅˆ Silver Sponsors

๐Ÿฅ‰ Bronze Sponsors


Status: Test Lint

Quickstart

  • Via CDN: <script src="https://unpkg.com/vue-i18n@9"></script>
  • In-browser playground on CodeSandbox
  • Add it to an existing Vue Project:
    npm install vue-i18n@9

Changes from Vue I18n v8

Please consult the Migration Guide.

๐Ÿ™‹โ€โ™‚๏ธ About support for v9 and earlier

  • v7 and v8: we will follow Vue v2 maintenance lifespan

๐Ÿญ Examples

See the examples directory.

The examples are offered in the following two API styles:

  • composition
    • Examples using the new Vue I18n API for Vue 3 Composition API
  • legacy
    • Examples using the Vue I18n API that are almost compatible with Vue I18n v8.x

๐Ÿ“ฆ Main Packages

Package NPM
vue-i18n vue-i18n
vue-i18n-bridge vue-i18n-bridge
@intlify/core @intlify/core
@intlify/core-base @intlify/core-base
@intlify/message-compiler @intlify/message-compiler
@intlify/shared @intlify/shared

๐Ÿƒ Other Projects

Project NPM Repo
Vue I18n Extensions @intlify/vue-i18n-extensions intlify/vue-i18n-extentions
ESLint Plugin @intlify/eslint-plugin-vue-i18n intlify/eslint-plugin-vue-i18n
CLI intlify/cli intlify/cli
Unplugin (Vite) plugin @intlify/unplugin-vue-i18n intlify/unplugin-vue-i18n
Vue Jest Plugin vue-i18n-jest intlify/vue-i18n-jest
Vue I18n Locale Message Tools vue-i18n-locale-message intlify/vue-i18n-locale-message

๐Ÿ’ช Contribution

Please make sure to read the Contributing Guide before making a pull request.

ยฉ๏ธ License

MIT

vue-i18n-next's People

Contributors

bobbiegoede avatar bponomarenko avatar demivan avatar dependabot-preview[bot] avatar dependabot[bot] avatar dhritzkiv avatar docnoe avatar exoego avatar jbtje avatar kazupon avatar kimuraz avatar lazzzis avatar littleboarx avatar lukaszkokot avatar mannil avatar mergify[bot] avatar munierujp avatar noy4 avatar nozomuikuta avatar ota-meshi avatar peteralfredlee avatar raiondesu avatar renovate-bot avatar renovate[bot] avatar sebwas avatar siegfriedehret avatar ts0307 avatar xfq avatar xuhongbo avatar yannbriancon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-i18n-next's Issues

My doubts about the architecture of vue-i18n-next

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

  • What if you want to load the translations later, using an API call?
  • Or even add new translations on the fly?
  • Are translations reactive at all?
  • How would you create a reusable component, shared by multiple projects, carrying its own translations?

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?

How to load messages asynchronously?

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

Cannot find module '@intlify/core/src/runtime'

vue & vue-i18n version

  • vue: 3.0.4
  • vue-i18n: 9.0.0-beta.12

Steps to reproduce

Install package with npm as a dependency -> check dist files of package in node_modules.

What is Expected?

All "internal" files to the package should logically be included when installing it.

What is actually happening?

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';

Crash when running on Cloudflare Worker (SSR) due to string evaluation

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.

vue & vue-i18n version

ex:

  • vue: 3.0.x
  • vue-i18n: 9.0.0-beta.8

Steps to reproduce

Use vue-i18n in any Vue app running on a Cloudflare Worker (SSR, different from Node.js environment).

What is Expected?

It should work.

What is actually happening?

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!

unable to load messages with error Type 'Record<string, LocaleMessageDictionary<string>>' is not assignable to type 'Record<string, LocaleMessageDictionary<VueMessageType>>'.

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 | })


Missing i18n instance in the docs

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')

how to use the production build (*.prod.js)

vue & vue-i18n version

  • vue: ^3.0.4
  • vue-i18n: ^9.0.0-beta.10

What is Expected?

Need manual/guide to make/configure the production build.
Or disable that warning message in Console.

What is actually happening?

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.

prod

error: Invalid token in placeholder: '$

vue & vue-i18n version

ex:

  • vue: 3.0.0-0
  • vue-i18n: 9.0.0-beta.3

Reproduction Link

https://jsfiddle.net/x0o2cL67/

Steps to reproduce

How to output 'xxx: { $100, $xxx }' string directly, some scenarios need to output special characters.

What is Expected?

Output string with no error.

What is actually happening?

image

can't change local

vue & vue-i18n version

"vue": "^3.0.2",
"vue-i18n": "^9.0.0-beta.6",
"@intlify/vue-i18n-loader": "^2.0.0-beta.1",

Reproduction Link

Steps to reproduce

as mentioned here - https://kazupon.github.io/vue-i18n/guide/locale.html

	methods: {
		changeLanguage: function (language) {
			this.$root.$i18n.locale = language;
		},
	},

What is Expected?

all messages should change to selected local

What is actually happening?

doesn't change

Warning: [vue-i18n] Not found parent composer. use the global composer.

Steps done:

  • installed latest vue version
  • installed latest vue-i18n beta version

vue & vue-i18n version

  • vue 3.0.2
  • vue-i18n: 9.0.0-beta.6

Reproduction link

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?

Cannot read property '__disableEmitter'

vue & vue-i18n version

  • vue: 3.0.0
  • vue-i18n: 9.0.0-beta.4

What is actually happening?

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

Use `@formatjs/intl`?

๐Ÿ‘‹ 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-i18n] Object Spread { ...options } in VueI18n Next not supported by all Browsers

Greetings,
Thanks a lot for your work!

VueI18n is using some object spread operations which are not converted to <ES2018.

vue & vue-i18n version

  • vue: 3.0.0
  • vue-i18n: 9.0.0-beta.6

What is Expected?

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

  • vue-i18n.cjs.js: Unexpected token (1137:52)
  • vue-i18n.global.js: Unexpected token (1516:54)

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

Never install the latest alpha version by npm

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:

  • Update package.json file manually as "vue-i18n": "^9.0.0-alpha.13",
  • And run npm update
  • Then my Vue project doesn't recognize 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.

Usage of @-symbol does not work

vue & vue-i18n version

  • vue: 3.0.0
  • vue-i18n: 9.0.0-beta.2

Steps to reproduce

I have an e-mail address in a translation instruction that contains the @ sign.

My drawing instruction:

The call:

<p>{{ t('email') }}</p>

What is Expected?

I expect it to be translated 1 to 1.

What is actually happening?

Error on the console is thrown. But Webpack can compile it. So the error will happen at runtime.
image

useScope inconsistency

vue & vue-i18n version

"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",

Steps to reproduce

Add useI18n() without any options to a component

  // This will set useScope=global
  setup() {
    return useI18n()
  },

What is Expected?

The component still uses local scope, since that way localization strings added by the vue loader can be used.

What is actually happening?

The component uses global scope. More confusing: if you add any option (e.g. the locale), the component will use local scope.

Workaround

    return useI18n({
      useScope: 'local',
    })

`beforeDestroy` has been renamed to `beforeUnmount`

vue & vue-i18n version

  • vue: 3.0.0-beta.14
  • vue-i18n: 9.0.0-beta.1

Reproduction Link

Steps to reproduce

export const i18n = createI18n({
locale: 'zh-cn',
legacy: true,
....

What is Expected?

[Vue warn]: beforeDestroy has been renamed to beforeUnmount.

What is actually happening?

[vue-i18n] Not found 'hello' key in 'en' locale messages.

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

Integrating with Vue Router for localizing route paths structure

@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?

Usage with Vue 2 and @vue/composition-api

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!

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.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
npm
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.3
  • vitest ^1.3.0
  • vue 3.4.25
  • typescript ^5.0.4
  • node >= 18
  • vue 3.4.25
  • 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

  • Check this box to trigger a request for Renovate to run again on this repository

About display problems after changing language

vue & vue-i18n version

  • vue: 3.0.0-alpha.10
  • vue-i18n: 9.0.0-alpha.0

Reproduction Link

Steps to reproduce

After switching languages

image
image

What is Expected?

After switching languages, the fields selected in the drop-down box are not changed to the corresponding language

What is actually happening?

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

Usage outside of vue components

vue & vue-i18n version

ex:

  • vue: 3.0.0-rc.10
  • vue-i18n: 9.0.0-beta.1

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"
image

Thank you for your work and help :)

Migrating to vue3 error

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)

Messages won't update if used inside a slot

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.

Console warning:

 [vue-i18n] Not found parent composer. use the global composer.

vue & vue-i18n version

  • vue: 3.0.0-beta.14
  • vue-i18n: 9.0.0-alpha.10

Reproduction Link

Legacy global scope example updated with slot
https://gist.github.com/hdahlheim/cc3f74474f8040bbe7d68cd29fb7f639

Steps to reproduce

Place any $t()/t() calls or i18n-t components inside the slot of a custom component and change the language.

What is Expected?

The message inside of the slot updates.

What is actually happening?

The message stays the same as on the first render.

The README file in this repo has some bad links - [404:NotFound]

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:

Vue 3 with dynamic locales

vue & vue-i18n version

What is Expected?

Migration of previously working state.

What is actually happening?

Cannot access translations in Vue components. I am using webpacker WITHOUT asset pipeline.

Working code in vue 2.X

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;

Migrating to Vue 3

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

What's unclear:

  • do I have to somehow make $t available first by importing it?
  • how to access $t globally in all components - is the setup() section in createApp actually the right way to do it?
  • how to adjust the configuration so that $t is available in all of them - globbing all components so they don't have to be imported by name one by one

Could you help with the migration? Many Rails/Go developers would need this for webapps where Vue is the frontend.
Thank you.

Datetime Formatting Not found 'short' key in 'en' locale message

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>

"unexpected error" when not adding .use(createI18n())

vue & vue-i18n version

"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",

Steps to reproduce

Add vue-i18n dependencies. In your component, include:

  setup() {
    return useI18n()
  },

Do not include any global config in your main app (no createI18n)

What is Expected?

An error indicating what happened and suggesting a solution to fix this.

What is actually happening?

The console says "unexpected error"

This is caused by:

throw createI18nError(15);

In this case, a more descriptive error message should be printed.

No transaltion for nested or child components

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

vue & vue-i18n version

  • vue: 3.0.0-beta.1
  • vue-i18n: 9.0.0-alpha.16

Steps to reproduce

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.

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

File Login.vue
<template>
<div>
    {{ t("login.title") }}
</div>
</template>

<script>

	export default {
		name: 'Login',
		components: {
		}
	}
</script>

<style lang="scss">
</style>

File 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')

File i18n.js
import {createI18n} from 'vue-i18n'

const i18n = createI18n({
	locale: 'en',
	globalInstall: true,
	messages: {
		en: {'login.title': 'test'}
	}
})
export default i18n;

What is Expected?

I expect to translate the key inside the login view also and nested children.

What is actually happening?

Only the translation inside App.vue works, the translate for Login.vue does not work.

Screenshots

  • UI :
    image
  • Console :
    image

Curious why object/array returns from $t are removed?

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?

Exposing methods for Script Setup 'SFC Composition API Syntax Sugar'

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">?

Locale property of useI18n seems as it is not Reactive

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!

Changing locale dynamically does not work

vue & vue-i18n version

ex:

  • vue: 3.0.0-rc.1
  • vue-i18n: 9.0.0-alpha.11

Steps to reproduce

 <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

What is Expected?

Page text is changed as expected

What is actually happening?

Nothing is happen, but console.log(i18n.locale) shows i18n.locale has been changed successfully.

beta.11 regression: I18N interface no longer has an `install`function

vue & vue-i18n version

ex:

  • vue: 3.0.4
  • vue-i18n: 9.0.0-beta.11

Reproduction Link

cexbrayat/vue-cli-playground#2

Steps to reproduce

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.

What is Expected?

We should be able to use the i18n plugin with TS

What is actually happening?

We can't use the plugin as it does not compile with beta.11

v9.0.0-beta.3 published on latest tag

vue & vue-i18n version

  • vue-i18n: 9.0.0-beta.3

What is actually happening?

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!

Dynamic Language Change

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?

Suggestion: Do not use so many component properties

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-i18n: 9.0.0-beta.10 - Uncaught (in promise) TypeError: _ctx.$t is not a function

"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"
  }

Missing handler response not returned on translating missing key

vue & vue-i18n version

  • vue: 3.0.2
  • vue-i18n: 9.0.0-beta.6

Reproduction Link

https://codepen.io/pgbross/pen/YzWLBYy

Steps to reproduce

Create i18n with missing key handler
Translate missing key

Observe response string is the key not the output of the missing key handler.

What is Expected?

The output of the missing handler to be returned.

What is actually happening?

Translate key with no message and missing handler defined, the key is returned as the translation.

How to include explanatory descriptions for messages in vue-i18n/vue-i18n-next?

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

  1. https://www.mediawiki.org/wiki/Localisation_file_format#Metadata
  2. https://angular.io/guide/i18n#mark-text-for-translations

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

image

Dot separated keys no longer working in messages

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.

Doesn't render "%" character

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.