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.
97 lines (96 loc) • 3.39 kB
JavaScript
import { translationCacheKey } from "@i18n-micro/core/helpers";
import { STORAGE_CC_KEY } from "@i18n-micro/hmr/cache-keys";
import { CacheControl } from "@i18n-micro/utils/cache-control";
import { buildTranslationPayloadFetchRequest } from "@i18n-micro/utils/payload-url";
function getStorageCacheControl() {
const g = globalThis;
if (!g[STORAGE_CC_KEY]) {
g[STORAGE_CC_KEY] = new CacheControl();
}
return g[STORAGE_CC_KEY];
}
class TranslationStorage {
cc;
constructor() {
this.cc = getStorageCacheControl();
}
/**
* Configure cache limits. Call once from plugin with config values.
*/
configure(options) {
this.cc.configure(options);
}
// ==========================================================================
// HELPERS
// ==========================================================================
/** Plain clone before freeze — SSR payload chunks may be Vue reactive proxies. */
freezePlainClone(data) {
return Object.freeze(JSON.parse(JSON.stringify(data)));
}
getCacheKey(locale, routeName) {
return translationCacheKey(locale, routeName);
}
// ==========================================================================
// FETCH LOADER
// ==========================================================================
async fetchTranslations(locale, routeName, options) {
const request = buildTranslationPayloadFetchRequest({
apiBaseUrl: options.apiBaseUrl,
routeName,
locale,
isServer: import.meta.server,
baseURL: options.baseURL,
apiBaseClientHost: options.apiBaseClientHost,
apiBaseServerHost: options.apiBaseServerHost ?? (import.meta.server ? process.env.NUXT_I18N_APP_BASE_SERVER_HOST : void 0),
dateBuild: options.dateBuild,
routesLocaleLinks: options.routesLocaleLinks
});
return await $fetch(request.path, {
baseURL: request.baseURL,
params: request.params
});
}
// ==========================================================================
// PUBLIC API
// ==========================================================================
/**
* Seed translation cache from SSR payload (`useState('i18n-ssr-chunks')`).
* Called on client before the first fetch.
*/
seedFromSsrChunks(chunks) {
for (const [cacheKey, data] of Object.entries(chunks)) {
this.cc.set(cacheKey, this.freezePlainClone(data));
}
}
/**
* Synchronous cache check and retrieval.
* Returns data if cached (and not expired), otherwise null.
*/
getFromCache(locale, routeName) {
const cacheKey = this.getCacheKey(locale, routeName);
const cached = this.cc.get(cacheKey);
if (cached) {
return { data: cached, cacheKey };
}
return null;
}
/**
* Load translations (with caching).
* Returns data, cache key, and JSON for injection (server only).
*/
async load(locale, routeName, options) {
const cached = this.getFromCache(locale, routeName);
if (cached) return cached;
const cacheKey = this.getCacheKey(locale, routeName);
const data = await this.fetchTranslations(locale, routeName, options);
this.cc.set(cacheKey, this.freezePlainClone(data));
return { data: this.cc.get(cacheKey), cacheKey };
}
/**
* Clear cache and metadata.
*/
clear() {
this.cc.clear();
}
}
export const translationStorage = new TranslationStorage();