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.
61 lines (60 loc) • 2.5 kB
JavaScript
import path from "node:path";
import { watch } from "chokidar";
import { useStorage, useRuntimeConfig, defineNitroPlugin } from "#imports";
let watcherInstance = null;
export default defineNitroPlugin((nitroApp) => {
if (watcherInstance) {
return;
}
const config = useRuntimeConfig();
const i18nConfig = config.i18nConfig;
if (!i18nConfig || process.env.NODE_ENV !== "development") {
return;
}
const log = (...args) => i18nConfig.debug && console.log("[i18n-hmr]", ...args);
const warn = (...args) => i18nConfig.debug && console.warn("[i18n-hmr]", ...args);
const translationsRoot = path.resolve(i18nConfig.rootDir, i18nConfig.translationDir);
log(`Watching for translation changes in: ${translationsRoot}`);
const storage = useStorage("assets:server");
const invalidateCache = async (filePath) => {
if (!filePath.endsWith(".json")) return;
const relativePath = path.relative(translationsRoot, filePath).replace(/\\/g, "/");
const isPageTranslation = relativePath.startsWith("pages/");
try {
const allKeys = await storage.getKeys("_locales:merged:");
if (isPageTranslation) {
const match = relativePath.match(/^pages\/([^/]+)\/(.+)\.json$/);
if (!match) return;
const pageName = match[1];
const locale = match[2];
const keyToRemove = `_locales:merged:${pageName}:${locale}`;
if (allKeys.includes(keyToRemove)) {
await storage.removeItem(keyToRemove);
log(`Invalidated page cache: ${keyToRemove}`);
}
} else {
const match = relativePath.match(/^([^/]+)\.json$/);
if (!match) return;
const locale = match[1];
const keysToRemove = allKeys.filter((key) => key.endsWith(`:${locale}`));
if (keysToRemove.length > 0) {
await Promise.all(keysToRemove.map((key) => storage.removeItem(key)));
log(`Invalidated ALL page caches for locale '${locale}'. Removed ${keysToRemove.length} entries.`);
}
}
} catch (e) {
warn("Failed to invalidate server cache for", filePath, e);
}
};
const watcher = watch(translationsRoot, { persistent: true, ignoreInitial: true, depth: 5 });
watcher.on("add", invalidateCache);
watcher.on("change", invalidateCache);
watcher.on("unlink", invalidateCache);
watcherInstance = watcher;
nitroApp.hooks.hook("close", async () => {
if (watcherInstance) {
await watcherInstance.close();
watcherInstance = null;
}
});
});