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.

61 lines (60 loc) 2.5 kB
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; } }); });