UNPKG

nuxt-i18n-micro

Version:

Nuxt I18n Micro is a lightweight, high-performance internationalization module for Nuxt, designed to handle multi-language support with minimal overhead, fast build times, and efficient runtime performance.

64 lines (63 loc) 2.87 kB
import { resolve, join } from "node:path"; import { readFile } from "node:fs/promises"; import { defineEventHandler } from "h3"; import { useRuntimeConfig, createError, useStorage } from "#imports"; let storageInit = false; function deepMerge(target, source) { for (const key in source) { if (key === "__proto__" || key === "constructor") continue; if (Array.isArray(source[key])) { target[key] = source[key]; } else if (source[key] instanceof Object) { target[key] = target[key] instanceof Object ? deepMerge(target[key], source[key]) : source[key]; } else { target[key] = source[key]; } } return target; } export default defineEventHandler(async (event) => { const { page, locale } = event.context.params; const config = useRuntimeConfig(); const { rootDirs, debug, translationDir, fallbackLocale, customRegexMatcher } = config.i18nConfig; const { locales } = config.public.i18nConfig; if (customRegexMatcher && locales && !locales.map((l) => l.code).includes(locale)) { throw createError({ statusCode: 404 }); } const currentLocaleConfig = locales?.find((l) => l.code === locale) ?? null; const getTranslationPath = (locale2, page2) => page2 === "general" ? `${locale2}.json` : `pages/${page2}/${locale2}.json`; let translations = {}; const serverStorage = useStorage("assets:server"); if (!storageInit) { if (debug) console.log("[nuxt-i18n-micro] clear storage cache"); await Promise.all((await serverStorage.getKeys("_locales")).map((key) => serverStorage.removeItem(key))); storageInit = true; } const cacheName = join("_locales", getTranslationPath(locale, page)); const isThereAsset = await serverStorage.hasItem(cacheName); if (isThereAsset) { const rawContent = await serverStorage.getItemRaw(cacheName) ?? {}; return typeof rawContent === "string" ? JSON.parse(rawContent) : rawContent; } const createPaths = (locale2) => rootDirs.map((dir) => ({ translationPath: resolve(dir, translationDir, getTranslationPath(locale2, page)), name: `_locales/${getTranslationPath(locale2, page)}` })); const paths = [ ...fallbackLocale && fallbackLocale !== locale ? createPaths(fallbackLocale) : [], ...currentLocaleConfig && currentLocaleConfig.fallbackLocale ? createPaths(currentLocaleConfig.fallbackLocale) : [], ...createPaths(locale) ]; for (const { translationPath, name } of paths) { try { if (debug) console.log("[nuxt-i18n-micro] load locale", translationPath, name); const content = await readFile(translationPath, "utf-8"); const fileContent = JSON.parse(content); translations = deepMerge(translations, fileContent); } catch (e) { if (debug) console.error("[nuxt-i18n-micro] load locale error", e); } } await serverStorage.setItem(cacheName, translations); return translations; });