Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/modernice/vue-i18n-modules
Lazy-loaded, namespaced messages for vue-i18n.
https://github.com/modernice/vue-i18n-modules
i18n lazy messages module namespace vue vue-i18n
Last synced: about 2 hours ago
JSON representation
Lazy-loaded, namespaced messages for vue-i18n.
- Host: GitHub
- URL: https://github.com/modernice/vue-i18n-modules
- Owner: modernice
- License: mit
- Created: 2022-08-23T12:12:41.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-26T13:53:15.000Z (about 2 months ago)
- Last Synced: 2024-10-31T11:19:11.141Z (17 days ago)
- Topics: i18n, lazy, messages, module, namespace, vue, vue-i18n
- Language: TypeScript
- Homepage:
- Size: 691 KB
- Stars: 6
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# vue-i18n-modules
An extension for [vue-i18n](https://github.com/intlify/vue-i18n-next) that
provides namespaced lazy-loading of messages, as opposed to the default behavior
of vue-i18n, which always loads all messages for a specific locale.## Introduction
Large applications that use vue-i18n for internationaliztion often have a large
amount of message files for different parts of the application. For better
performance, it is desirable to only load a set of messages when they're
actually needed, instead of loading all messages for a specific locale all at
once.### Limitations
- Only supports vue-i18n's [Composition API](https://vue-i18n.intlify.dev/guide/advanced/composition.html); does not support legacy mode
- Currently only supports Vite's `import.meta.glob` for loading message files
- Message directory must be organized in a specific way## Installation
### Vue
```sh
npm i @modernice/vue-i18n-modulespnpm i @modernice/vue-i18n-modules
yarn add @modernice/vue-i18n-modules
```### Nuxt
```sh
npm i @modernice/nuxt-i18n-modulespnpm i @modernice/nuxt-i18n-modules
yarn add @modernice/nuxt-i18n-modules
```## Setup
### Nuxt
Add the module to your `nuxt.config`:
```ts
// nuxt.config.ts
export default defineNuxtModule({
modules: ['@modernice/nuxt-i18n-modules'],i18nModules: {
dictionary: 'path/to/messages', // defaults to ./dictionary
initial: ['foo', 'bar'] // initial messages are loaded for every page
}
})
```### Vue
```ts
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import { createExtension, createPlugin } from 'vue-i18n-modules'
import { createGlobLoader } from 'vue-i18n-modules/vite'// First create the vue-i18n instance.
const i18n = createI18n({
// Legacy mode is not supported!
legacy: false,
})// Setup a loader for message files in the `./messages` directory.
const loader = createGlobLoader(import.meta.glob('./messages/**/*.json'), {
// The prefix allows you to reference/load message modules without
// having to specify the full path to the directory.
prefix: './messages/'
})// Create the extension from the vue-i18n instance and module loader.
const extension = createExtension({ i18n, loader })// Create the Vue plugin from the extension.
const plugin = createPlugin(extension)createApp()
.use(i18n)
.use(plugin)
.mount('#app')
```## Basic usage
Given that your message modules are in the `./messages` directory, you must
create a directory structure like this:- `./messages`
- `./foo`
- `./en.json`
- `./de.json`
- `./fr.json`
- `./foobar`
- `./en.json`
- `./de.json`
- `./fr.json`
- `./bar`
- `./en.json`
- `./de.json`
- `./fr.json`
- `./barbaz`
- `./en.json`
- `./de.json`
- `./fr.json`The above directory structure defines 4 modules: "foo", "bar", "foo.foobar", and
"bar.barbaz". Each module provides its messages for the locales that are configured
in the vue-i18n instance.Given that `./messages/foo/foobar/en.json` has the following contents:
```json
{
"page": {
"title": "Hello, Foo!"
}
}
```You can lazy-load and translate the title like this:
```ts
// Within a Vue setup function
import { useExtension } from 'vue-i18n-modules'const { loadModule, translate } = useExtension()
// Loads the messages of the "foo.foobar" module.
await loadModule('foo.foobar')// Translate the title in the currently active locale.
const title = translate('foo.foobar', 'page.title')
```The `translate` function utilities vue-i18n's translate function internally,
so you can pass vue-i18n's translate options to this function.## Typed modules
You can define types for your message modules by augmenting the `DefineModules`
interface. When defining at least one module, this extension enforces strictness
in module names passed to the `translate` function.For example, you could create `./messages/foo/foobar/index.ts` to define the
type of the `foo.foobar` module:```ts
// ./messages/foo/foobar/index.ts
import type foobar from './en.json'/**
* Foobar messages.
*/
export type Foobar = typeof foobar
```Then augment the `DefineModules` interface to enable strict typing:
```ts
// in a project-wide *.d.ts file
import { Foobar } from './messages/foo/foobar/index'declare module '@modernice/vue-i18n-modules' {
interface DefineModules {
'foo.foobar': Foobar
}
}
```If at least one module is defined, the `translate` function only accepts defined
module names instead of arbitrary strings. The following will raise a TypeScript
error:```ts
// Within a Vue setup function
import { useExtension } from 'vue-i18n-modules'const { loadModule, translate } = useExtension()
// This will not work
await loadModule('unknown-module-name')// This won't work either
const title = translate('unknown-module-name', 'some.key')// This also won't work because the key does not exist in the file
const title = translate('foo.foobar', 'some.key')
```## useMessages()
Instead of `useExtension()`, you can call `useMessages()` to get a translate
function for a specific module:```ts
// Within a Vue setup function
import { useMessages } from 'vue-i18n-modules'const { translate } = useMessages('foo.foobar', {
// Immediately load the module within `onServerPrefetch`
// and/or `onMounted`.
load: true,
})// Now you can omit the module name
const title = translate('page.title')
```### Middleware
A middleware for loading message modules is provided for Nuxt applications:
```ts
// Within a Vue setup functiondefinePageMeta({
middleware: 'i18n:messages',// Load the "foo" and "foo.bar" message modules in a
// middleware before rendering the page.
translate: ['foo', 'foo.bar'],
})
```## License
[MIT](./LICENSE)