lazy load locale based on user settings

This commit is contained in:
vabene1111
2024-07-31 16:59:02 +02:00
parent 8a4ffc5e0c
commit c02523ee51
2 changed files with 39 additions and 47 deletions

View File

@@ -17,8 +17,8 @@ import RecipeEditPage from "@/pages/RecipeEditPage.vue";
import MealPlanPage from "@/pages/MealPlanPage.vue"; import MealPlanPage from "@/pages/MealPlanPage.vue";
import SearchPage from "@/pages/SearchPage.vue"; import SearchPage from "@/pages/SearchPage.vue";
import TestPage from "@/pages/TestPage.vue"; import TestPage from "@/pages/TestPage.vue";
import {createI18n} from "vue-i18n"; import {createI18n, I18n} from "vue-i18n";
import {getLocale, loadLocaleMessages, setI18nLanguage, setupI18n, SUPPORT_LOCALES} from "@/i18n"; import {getLocale, loadLocaleMessages, SUPPORT_LOCALES} from "@/i18n";
const routes = [ const routes = [
{path: '/', component: StartPage, name: 'view_home'}, {path: '/', component: StartPage, name: 'view_home'},
@@ -44,15 +44,16 @@ if (locale == null || !SUPPORT_LOCALES.includes(locale)) {
} }
const localeMessages = await import((`../../locales/${locale}.json`)) const localeMessages = await import((`../../locales/${locale}.json`))
console.log(localeMessages, de) console.log(localeMessages, de)
const i18n = setupI18n({ const i18n = createI18n({
legacy: false, legacy: false,
locale: locale, locale: 'en',
fallbackLocale: 'en', fallbackLocale: 'en',
messages: { messages: {
en, de en
} }
}) }) as I18n
loadLocaleMessages(i18n, locale).then(r => {})
const app = createApp(App) const app = createApp(App)

View File

@@ -1,9 +1,7 @@
import {nextTick, isRef} from 'vue' import {nextTick, isRef} from 'vue'
import {createI18n} from 'vue-i18n'
import type { import type {
I18n, I18n,
I18nOptions,
Locale, Locale,
VueI18n, VueI18n,
Composer, Composer,
@@ -16,9 +14,15 @@ import type {
* https://github.com/intlify/vue-i18n/blob/master/examples/lazy-loading/vite/src/i18n.ts * https://github.com/intlify/vue-i18n/blob/master/examples/lazy-loading/vite/src/i18n.ts
*/ */
// TODO not sure why/if this is needed, comment out for now and see if anything breaks /**
* constant list of supported locales for app to check if requested locale is supported
*/
export const SUPPORT_LOCALES = getSupportedLocales() export const SUPPORT_LOCALES = getSupportedLocales()
/**
* loop trough translation files to determine for which locales a translation is available
* @return string[] of supported locales
*/
function getSupportedLocales() { function getSupportedLocales() {
let supportedLocales: string[] = [] let supportedLocales: string[] = []
let localeFiles = import.meta.glob('@/locales/*.json'); let localeFiles = import.meta.glob('@/locales/*.json');
@@ -28,26 +32,19 @@ function getSupportedLocales() {
return supportedLocales return supportedLocales
} }
function isComposer( /**
instance: VueI18n | Composer, * determines something about the way Vue i18n is installed/setup?
mode: I18nMode * @param instance
): instance is Composer { * @param mode
*/
function isComposer( instance: VueI18n | Composer, mode: I18nMode ): instance is Composer {
return mode === 'composition' && isRef(instance.locale) return mode === 'composition' && isRef(instance.locale)
} }
export function setupI18n2() { /**
let locale = document.querySelector('html')!.getAttribute('lang') * get the currently active locale of Vue i18n
if (locale == null || !SUPPORT_LOCALES.includes(locale)) { * @param i18n instance of Vue i18n
locale = 'en' */
}
const i18n = createI18n({locale: locale})
return i18n
}
export function getLocale(i18n: I18n): string { export function getLocale(i18n: I18n): string {
if (isComposer(i18n.global, i18n.mode)) { if (isComposer(i18n.global, i18n.mode)) {
return i18n.global.locale.value return i18n.global.locale.value
@@ -56,6 +53,11 @@ export function getLocale(i18n: I18n): string {
} }
} }
/**
* set the active locale (determining which messages to show) for Vue i18n
* @param i18n instance of Vue i18n
* @param locale string locale code to set (should be in SUPPORT_LOCALES)
*/
export function setLocale(i18n: I18n, locale: Locale): void { export function setLocale(i18n: I18n, locale: Locale): void {
if (isComposer(i18n.global, i18n.mode)) { if (isComposer(i18n.global, i18n.mode)) {
i18n.global.locale.value = locale i18n.global.locale.value = locale
@@ -64,37 +66,26 @@ export function setLocale(i18n: I18n, locale: Locale): void {
} }
} }
export function setupI18n(options: I18nOptions = {locale: 'en'}): I18n {
const i18n = createI18n(options)
setI18nLanguage(i18n, options.locale!)
return i18n
}
export function setI18nLanguage(i18n: I18n, locale: Locale): void {
setLocale(i18n, locale)
/**
* NOTE:
* If you need to specify the language setting for headers, such as the `fetch` API, set it here.
* The following is an example for axios.
*
* axios.defaults.headers.common['Accept-Language'] = locale
*/
// should be done by django
// document.querySelector('html')!.setAttribute('lang', locale)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const getResourceMessages = (r: any) => r.default || r const getResourceMessages = (r: any) => r.default || r
/**
* load specified locale messages from server and set the locale as active
* @param i18n instance of Vue i18n
* @param locale string locale code to set (should be in SUPPORT_LOCALES)
*/
export async function loadLocaleMessages(i18n: I18n, locale: Locale) { export async function loadLocaleMessages(i18n: I18n, locale: Locale) {
// load locale messages // load locale messages
const messages = await import(`./locales/${locale}.json`).then( const messages = await import(`./locales/${locale}.json`).then(
getResourceMessages getResourceMessages
) )
// set locale and locale message // set messages for locale
i18n.global.setLocaleMessage(locale, messages) i18n.global.setLocaleMessage(locale, messages)
// switch to given locale
setLocale(i18n, locale)
console.log('loaded user locale')
return nextTick() return nextTick()
} }