{"id":19201431,"url":"https://github.com/padcom/vue-i18n","last_synced_at":"2025-05-12T12:42:56.480Z","repository":{"id":203691982,"uuid":"710212135","full_name":"padcom/vue-i18n","owner":"padcom","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-04T07:50:23.000Z","size":113,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-20T13:36:07.531Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/padcom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-26T08:44:30.000Z","updated_at":"2024-10-04T07:50:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"12829dc3-c01a-4263-a761-e7bc71c6f920","html_url":"https://github.com/padcom/vue-i18n","commit_stats":null,"previous_names":["padcom/vue-i18n"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padcom%2Fvue-i18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padcom%2Fvue-i18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padcom%2Fvue-i18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padcom%2Fvue-i18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/padcom","download_url":"https://codeload.github.com/padcom/vue-i18n/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253742400,"owners_count":21957018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T12:38:45.850Z","updated_at":"2025-05-12T12:42:56.449Z","avatar_url":"https://github.com/padcom.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simplified and unified Vue.js i18n\n\nThis package implements simplified mechanism for internationalization (i18n) of components in Vue.js.\n\n## TLDR;\n\nIf you want to see all the bits and pieces in action check out the [example](https://github.com/padcom/vue-i18n-example-vue3)\n\n## Installation\n\nThere are 2 parts to making this system work:\n\n1. Vite plugin\n2. Vue.js plugin or context creation (for webcomponents)\n\n### Installing Vite plugin\n\nTo install the Vite plugin first install the package:\n\n```\nnpm install --save-dev @padcom/vite-plugin-vue-i18n\n```\n\nand then add it to your `vite.config.js`:\n\n```typescript\nimport { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport i18n from '@padcom/vite-plugin-vue-i18n'\n\nexport default defineConfig({\n  plugins: [\n    vue(),\n    i18n(),\n  ]\n})\n```\n\nNothing really fancy, but needs to be done so that Vite understands how to process the `\u003ci18n\u003e` blocks in `.vue` files.\n\n### Installing the Vue.js part\n\nFirst things first, you need to install the part that provides the actual i18n capabilities:\n\n```\nnpm install --save-dev @padcom/vue-i18n\n```\n\n### Providing messages context\n\nIn contrast to the original `vue-i18n` plugin this one does not provide a global function that can inject messages from the global scope. Instead, everything is done using composition functions and Vue's native `provide`/`inject`.\n\n#### For applications\n\nFor applications the easiest way to do it is to install the provided Vue.js plugin when creating the application:\n\n```typescript\nimport { createApp } from 'vue'\nimport { createI18n } from '@padcom/vue-i18n'\n\nimport App from './App.vue'\n\nconst messages = {\n  en: {\n    hello: 'Hello, world!',\n  },\n}\n\ncreateI18n({ messages })\n\ncreateApp(App)\n  .mount('#app')\n```\n\n#### For anything else\n\nIn the case of for example webcomponents, where the application instance is just not available there is no way to use a plugin approach like that. But no worries - this package has you covered! Instead of using a Vue.js plugin you can create the necessary context yourself:\n\n`Host.ce.vue` - a file acting as the webcomponent host for your application:\n\n```vue\n\u003ctemplate\u003e\n  \u003cSomeComponentThatWantsToUseTranslations /\u003e\n\u003c/template\u003e\n\n\u003cscript lang=\"ts\" setup\u003e\nimport { createI18Context } from '@padcom/vue-i18n'\nimport SomeComponentThatWantsToUseTranslations from '...'\n\nconst messages = {\n  en: {\n    hello: 'Hello, world!',\n  },\n}\n\ncreateI18Context({ messages })\n\u003c/script\u003e\n```\n\n### Messages structure in real life\n\nYou can get the `messages` from anywhere - here we just provide them in the same file to make it easier for presentation but in real life you might want to extract them to a folder structure like the original [vue-i18n](https://kazupon.github.io/vue-i18n/) plugin suggests:\n\n```\nsrc\n  + i18n\n    + index.ts\n    + locale\n      + en.ts\n      + de.ts\n      ...\n```\n\nwhere `src/i18n/index.ts` contains re-exports of all the different messages for languages:\n\n```typescript\nexport { default as en } from './locale/en'\nexport { default as de } from './locale/de'\n```\n\nand the individual message files just export the messages as follows:\n\n```typescript\nexport default {\n  hello: 'Hello, world!',\n}\n```\n\nWith that kind of structure, this is how you would import the messages when you want to import your messages in `./src/i18n.js` or when you create the injection context manually:\n\n```typescript\nimport * as messages from './locale'\n\nexport const i18n = createI18n({\n  messages,\n})\n```\n\nand then in the `main.ts` of your application you simply import the module:\n\n```typescript\nimport './i18n'\n```\n\nOf course this is the most extensive version of the configuration. You can do it all in `main.ts` if your application is small enough:\n\n```typescript\nimport { createApp } from 'vue'\nimport { createI18n } from '@padcom/vue-i18n'\n\ncreateI18n({\n  messages: {\n    en: {\n      hello: 'Hello, world!',\n    },\n  },\n})\n\ncreateApp(App).mount('#app')\n```\n\n## Usage\n\nOnce you've installed and configured everything using this system is very simple:\n\n```vue\n\u003ctemplate\u003e\n  \u003ch1\u003e{{ t('message') }}\u003c/h1\u003e\n\u003c/template\u003e\n\n\u003cscript lang=\"ts\" setup\u003e\nimport { useI18n } from '@padcom/vue-i18n'\n\nconst { t } = useI18n()\n\u003c/script\u003e\n\n\u003ci18n\u003e\n{\n  \"en\": {\n    \"message\": \"Hello, world!\",\n  },\n  \"de\": {\n    \"message\": \"Hallo Welt!\",\n  }\n}\n\u003c/i18n\u003e\n```\n\n### Forcing resolution to use global messages only\n\nSometimes you might have duplicated message ids. In general you should try to avoid it as it makes reasoning about the code more difficult. Nevertheless, real world sometimes makes us do things we will regret later on and this system is not going to stand in your way.\n\nYou can enforce the `t` to use global messages by specifying the `useScope` key when calling `useI18n()`:\n\n```typescript\nconst { t } = useI18n({ useScope: 'global' })\n```\n\n### Disabling global messages resolution\n\nSometimes you might want your component to only use local translations. This system has you covered:\n\n```typescript\nconst { t } = useI18n({ useScope: 'local' })\n```\n\nThe default value for `useScope` is `'local-first'`, which means you'll get the the local value if defined or else the system will default to global scope.\n\n### Language selection\n\nThe system implements a simplistic, but powerful resolution system to get the message.\n\nThere are 2 locales that you can choose from:\n\n1. `locale`\n2. `fallbackLocale`\n\nBoth are initialized to the country code of the client's browser (e.g. `'en'`). But you can change them however you'd like either when installing the application plugin:\n\n```typescript\ncreateApp(App)\n  .use(i18n, {\n    messages,\n    locale: 'xy',\n    fallbackLocale: 'au'\n  })\n  .mount('#app')\n```\n\nor when creating the context:\n\n```typescript\nconst { locale, fallbackLocale } = createI18Context({\n  messages,\n  locale: 'xy',\n  fallbackLocale: 'au',\n})\n```\n\nThe message resolution is as follows:\n\n1. Try to resolve the given key using `locale` from `\u003ci18n\u003e` provided keys\n2. Try to resolve the given key using `fallbackLocale` from `\u003ci18n\u003e` provided keys\n3. Try to resolve the given key using global scope messages using `locale`\n4. Try to resolve the given key using global scope messages using `fallbackLocale`\n\n### Reacting to changes in selected locale\n\nWhen you want to react to when the locale is changed you'd use a Vue.js' watch to do so:\n\n```typescript\nimport { watch } from 'vue'\nimport { useI18n } from '@padcom/vue-i18n'\n\nconst { locale } = useI18n()\nwatch(locale, newLocale =\u003e {\n  console.log('Locale changed to', newLocale)\n})\n```\n\n## Closing thoughts\n\nThis internationalization system was created specifically because the original [vue-i18n](https://kazupon.github.io/vue-i18n) plugin makes it impossible to use it in the context of webcomponents. It's a design choice they have made and that's not going to change any time soon.\n\nHowever, if you don't need webcomponents interoperability and you're happy with how the original plugin works or if you need some of the advanced features (like pluralization or message arguments) then you should definitely go with the original one. It's much more robust and this system will probably never grow to be as complete as the original one is.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpadcom%2Fvue-i18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpadcom%2Fvue-i18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpadcom%2Fvue-i18n/lists"}