Skip to content

Commit

Permalink
feat: improve language detection and import locales dynamically
Browse files Browse the repository at this point in the history
  • Loading branch information
simonwep committed Nov 1, 2024
1 parent 90c5ed9 commit f300dc6
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 25 deletions.
40 changes: 19 additions & 21 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { createI18n, IntlNumberFormat } from 'vue-i18n';
import type en from './locales/en.json';
import cze from './locales/cze.json?url';
import de from './locales/de.json?url';
import en from './locales/en.json?url';
import ptbr from './locales/pt-br.json?url';
import tr from './locales/tr.json?url';

const imports: Record<string, () => Promise<{ default: string }>> = {
cze: () => import('./locales/cze.json?raw'),
en: () => import('./locales/en.json?raw'),
de: () => import('./locales/de.json?raw'),
tr: () => import('./locales/tr.json?raw'),
'pt-br': () => import('./locales/pt-br.json?raw')
} as const;
const localeUrls = { de, en, tr, 'pt-br': ptbr, cze };

export type MessageSchema = typeof en;
export const availableLocales = Object.keys(localeUrls);

const browserLocale = navigator.language.slice(0, 2).toLowerCase();
export const initialLocale =
(navigator.languages
.flatMap((v) => [v, ...v.split('-')])
.find((locale) => availableLocales.includes(locale)) as AvailableLocale) ?? 'en';

export const availableLocales = Object.keys(imports);
export const initialLocale = availableLocales.includes(browserLocale) ? browserLocale : 'en';

export type AvailableLocale = keyof typeof imports;
export type AvailableLocale = keyof typeof localeUrls;

const numberFormats: IntlNumberFormat = {
currency: {
Expand All @@ -29,19 +27,19 @@ const numberFormats: IntlNumberFormat = {
}
};

export const i18n = createI18n({
legacy: false,
locale: initialLocale
});
export const i18n = createI18n({ legacy: false });

export const changeLocale = async (locale: AvailableLocale, currency?: Intl.NumberFormatOptions) => {
const messages = JSON.parse((await imports[locale]()).default);
const numberFormat: IntlNumberFormat = { ...numberFormats, currency: { ...numberFormats.currency, ...currency } };
const messages = await fetch(localeUrls[locale]).then((res) => res.json());
const numberFormat: IntlNumberFormat = {
...numberFormats,
currency: { ...numberFormats.currency, ...currency }
};

document.documentElement.lang = locale;
i18n.global.setLocaleMessage(locale, messages);
i18n.global.setNumberFormat(locale, numberFormat);
i18n.global.locale.value = locale;
};

await changeLocale(browserLocale);
await changeLocale(initialLocale);
9 changes: 5 additions & 4 deletions src/store/state/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useStateHistory, useTime } from '@composables';
import { AvailableLocale, changeLocale, i18n } from '@i18n/index';
import { AvailableLocale, changeLocale } from '@i18n/index';
import { Storage } from '@storage/index';
import { moveInArrays, readFile, remove, uuid } from '@utils';
import { DeepReadonly, inject, reactive, readonly, ShallowRef, shallowRef, watch, watchEffect } from 'vue';
import { DeepReadonly, inject, reactive, readonly, ShallowRef, shallowRef, watch } from 'vue';
import { migrateApplicationState } from './migrator';
import { AvailableCurrency, Budget, BudgetGroup, BudgetYear, DataState, DataStates, DataStateV1 } from './types';
import { generateBudgetYear } from './utils';
Expand Down Expand Up @@ -95,8 +95,9 @@ export const createDataStore = (storage?: Storage): Store => {
};

watch(
() => [state.locale, state.currency],
([locale, currency]) => changeLocale(locale, { currency })
() => [state.locale, state.currency] as [AvailableLocale, AvailableCurrency],
([locale, currency]) => changeLocale(locale, { currency }),
{ immediate: true }
);

storage?.sync<DataState, DataState | DataStateV1>({
Expand Down

0 comments on commit f300dc6

Please sign in to comment.