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
JavaScript
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;
});