diff options
author | 2023-06-18 14:11:38 +0200 | |
---|---|---|
committer | 2023-06-18 14:33:58 +0200 | |
commit | ebfb872fae8c645cd7285f5dc6a07a2ef4139e99 (patch) | |
tree | e02f7b338d0e66665b9b826dc8deb465106e3b7d /src | |
parent | a6bbeaebd8e4f629ff20d6e2386be9c8734f6d8d (diff) | |
download | it-tools-ebfb872fae8c645cd7285f5dc6a07a2ef4139e99.tar.gz it-tools-ebfb872fae8c645cd7285f5dc6a07a2ef4139e99.tar.zst it-tools-ebfb872fae8c645cd7285f5dc6a07a2ef4139e99.zip |
chore(i18n): setup i18n plugin config
Diffstat (limited to 'src')
-rw-r--r-- | src/main.ts | 2 | ||||
-rw-r--r-- | src/pages/Home.page.vue | 3 | ||||
-rw-r--r-- | src/plugins/i18n.plugin.ts | 50 |
3 files changed, 54 insertions, 1 deletions
diff --git a/src/main.ts b/src/main.ts index e23cb91..36ba3b7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,6 +11,7 @@ import { naive } from './plugins/naive.plugin'; import App from './App.vue'; import router from './router'; +import { i18nPlugin } from './plugins/i18n.plugin'; registerSW(); @@ -18,6 +19,7 @@ const app = createApp(App); app.use(createPinia()); app.use(createHead()); +app.use(i18nPlugin); app.use(router); app.use(naive); app.use(plausible); diff --git a/src/pages/Home.page.vue b/src/pages/Home.page.vue index 01a7296..5c7c3c4 100644 --- a/src/pages/Home.page.vue +++ b/src/pages/Home.page.vue @@ -9,6 +9,7 @@ import { config } from '@/config'; const toolStore = useToolStore(); useHead({ title: 'IT Tools - Handy online tools for developers' }); +const { t } = useI18n(); </script> <template> @@ -48,7 +49,7 @@ useHead({ title: 'IT Tools - Handy online tools for developers' }); </transition> <div v-if="toolStore.newTools.length > 0"> - <n-h3>Newest tools</n-h3> + <n-h3>{{ t('home.categories.newestTools') }}</n-h3> <n-grid x-gap="12" y-gap="12" cols="1 400:2 800:3 1200:4 2000:8"> <n-gi v-for="tool in toolStore.newTools" :key="tool.name"> <ToolCard :tool="tool" /> diff --git a/src/plugins/i18n.plugin.ts b/src/plugins/i18n.plugin.ts new file mode 100644 index 0000000..a1a1000 --- /dev/null +++ b/src/plugins/i18n.plugin.ts @@ -0,0 +1,50 @@ +import type { App } from 'vue'; +import { createI18n } from 'vue-i18n'; +import type { Locale } from 'vue-i18n'; + +const i18n = createI18n({ + legacy: false, + locale: '', + messages: {}, +}); + +const localesMap = Object.fromEntries( + Object.entries(import.meta.glob('../../locales/*.yml')) + .map(([path, loadLocale]) => [path.match(/([\w-]*)\.yml$/)?.[1], loadLocale]), +) as Record<Locale, () => Promise<{ default: Record<string, string> }>>; + +export const availableLocales = Object.keys(localesMap); + +const loadedLanguages: string[] = []; + +function setI18nLanguage(lang: Locale) { + i18n.global.locale.value = lang as any; + if (typeof document !== 'undefined') { + document.querySelector('html')?.setAttribute('lang', lang); + } + return lang; +} + +export async function loadLanguageAsync(lang: string): Promise<Locale> { + if (i18n.global.locale.value === lang) { + return setI18nLanguage(lang); + } + + if (loadedLanguages.includes(lang)) { + return setI18nLanguage(lang); + } + + const messages = await localesMap[lang](); + + i18n.global.setLocaleMessage(lang, messages.default); + loadedLanguages.push(lang); + + return setI18nLanguage(lang); +} + +export const i18nPlugin = { + install: (app: App) => { + app.use(i18n); + loadLanguageAsync('en'); + }, +}; |