A simple Localization tool for Vuex/Vue (3)
I created it while developing with Laravel and was facing the problem, that I do not want load all translations at once.
- uses nearly the same function signatures provided by Laravel. See https://laravel.com/docs/8.x/helpers#method-trans
- contextual loading supported
- supports deferred loading
This is an experimental version and not indented for production usage yet.
npm i -D @gelbehexe/debbie-vuex-i18n
This is only required if you want to use contextual loading.
Create a language loader function e.g. lib/languageLoader.js
function languageLoader(contexts) {
return new Promise(function (resolve, reject) {
axios.get("/api/localization-context",{
params: {
contexts
}
}).resolve(data => {
resolve(data)
}).catch(err => reject(err))
})
}
In your main script e.g. app.js
import { createApp } from 'vue'
import App from './App.vue'
import store from "@/lib/store"; // your configured storage
import { translationPlugin } from "@gelbehexe/debbie-vuex-i18n"
// required only for contextual language loading
import languageLoader from "@/lib/languageLoader";
const app = createApp(App)
app.use(store)
// add plugin to app
app.use(translationPlugin, {
store,
languageLoader,
// your localization languages
locale: {
current: "de",
fallback: "en",
},
// Initial translations
// - for fallback locale only the keys
// which are not set in default language
// are needed
translations: {
en: {
en1: "English Only",
},
de: {
key1: "Deutsch 1",
key2: "Deutsch 2",
en_de: "Englisch und Deutsch"
}
}
})
app.mount('#app')
<templatep>
<div>
<h1>{{ t("key1") }}</h1>
<p>{{ t("context1.key1"}}</p>
</div>
</templatep>
<script>
import store from "@/lib/store"; // your configured storage
import { useTranslation } from "@gelbehexe/debbie-vuex-i18n"
export default {
name: "MyComponent",
setup() {
const { t, addDeferredLocalizationContext } = useTranslation(store)
addDeferredLocalizationContext("context1")
return {
t
}
}
}
</script>
Use v-vuex-translation
directive
to trigger previously deferred context loading.
You can use it without a value or with a method which
is called after loading.
Important: For a dynamic update after contextual loading it is necessary that the context is rendered.
<template>
<div v-vuex-translation="handleTranslationLoaded">
<div v-if="loading">Loading ...</div>
<!-- Important do not use v-else here -->
<div v-show="!loading">
<h1>{{ t("key2" }}</h1>
<slot></slot>
</div>
</div>
</template>
<script>
import { ref } from "vue"
import store from "@/lib/store"; // your configured storage
import { useTranslation } from "@gelbehexe/debbie-vuex-i18n"
export default {
name: "Layout",
setup() {
const loading = ref(true)
const { t } = useTranslation(store)
function handleTranslationLoaded() {
loading.value = false;
}
return {
t,
loading,
handleTranslationLoaded
}
}
}
</script>
useLocalizationContextLoader(store: Store): {getContextualLocalization: function, loadDeferredLocalization: function}
Returns the following functions as object:
Loads localization contexts directly
Loads previously added lazy contexts
If you are using the directive v-vuex-translation contextual loading is automatically triggered. Then there is no need for calling this function manually
useTranslation(store: Store): {trans: Function, transChoice: Function, t: Function, addDeferredLocalizationContext: Function}
Hint: Most of the functions are adopted from
Laravel Localization,
but not the __()
because eslint does not like the underscores. Except: The locale parameter is
not available.
Returns the following functions as object:
Simply translates a string.
See https://laravel.com/docs/8.x/helpers#method-trans
Get a translation according to an integer value.
See https://laravel.com/docs/8.x/helpers#method-trans-choice
Alias for trans
Adds a context for deferred loading.
For now there is only one directive:
You are not required to set all localization keys for fallback language since they are only used if not defined for default language
{
en: {
en1: "English Only",
},
de: {
key1: "Deutsch 1",
key2: "Deutsch 2",
en_de: "Englisch und Deutsch"
}
}
Data coming from LanguageLoader. Existing keys will be overridden.
For sure this could happen intentionally or accidentally.
{
en: {
"context1.key3": "Contextual English 3",
},
de: {
"context1.key1": "Context Deutsch 1",
"context1.key2": "Context Deutsch 2",
"context1.key4": "Context Deutsch 4",
},
}