UNPKG

vite-intlayer

Version:

A Vite plugin for seamless internationalization (i18n), providing locale detection, redirection, and environment-based configuration

200 lines 4.89 kB
import { parse } from "url"; import { getConfiguration } from "@intlayer/config"; import { localeDetector } from "@intlayer/core"; const intlayerConfig = getConfiguration(); const { internationalization, middleware } = intlayerConfig; const { locales: supportedLocales, defaultLocale } = internationalization; const { cookieName, headerName, prefixDefault, noPrefix, serverSetCookie, basePath = "" } = middleware; const intLayerMiddlewarePlugin = () => { return { name: "vite-intlayer-middleware-plugin", configureServer: (server) => { server.middlewares.use((req, res, next) => { if (req.url?.startsWith("/node_modules") || req.url?.startsWith("/@") || req.url?.split("?")[0].match(/\.[a-z]+$/i)) { return next(); } const parsedUrl = parse(req.url ?? "/", true); const originalPath = parsedUrl.pathname ?? "/"; const cookies = parseCookies(req.headers.cookie ?? ""); const cookieLocale = getValidLocaleFromCookie(cookies[cookieName]); const pathLocale = getPathLocale(originalPath); if (noPrefix) { handleNoPrefix({ req, res, next, originalPath, cookieLocale }); return; } handlePrefix({ req, res, next, originalPath, pathLocale, cookieLocale }); }); } }; }; const parseCookies = (cookieHeader) => { return cookieHeader.split(";").reduce( (acc, cookie) => { const [key, val] = cookie.trim().split("="); acc[key] = val; return acc; }, {} ); }; const getValidLocaleFromCookie = (locale) => { if (locale && supportedLocales.includes(locale)) { return locale; } return void 0; }; const getPathLocale = (pathname) => { const segments = pathname.split("/").filter(Boolean); const firstSegment = segments[0]; if (firstSegment && supportedLocales.includes(firstSegment)) { return firstSegment; } return void 0; }; const redirectUrl = (res, newUrl) => { res.writeHead(301, { Location: newUrl }); return res.end(); }; const rewriteUrl = (req, res, newUrl, locale) => { req.url = newUrl; if (locale && headerName) { res.setHeader(headerName, locale); } }; const constructPath = (locale, currentPath) => { const cleanBasePath = basePath.startsWith("/") ? basePath : `/${basePath}`; const normalizedBasePath = cleanBasePath === "/" ? "" : cleanBasePath; let newPath = `${normalizedBasePath}/${locale}${currentPath}`; if (!prefixDefault && locale === defaultLocale) { newPath = `${normalizedBasePath}${currentPath}`; } return newPath; }; const handleNoPrefix = ({ req, res, next, originalPath, cookieLocale }) => { let locale = cookieLocale ?? defaultLocale; if (!cookieLocale) { const detectedLocale = localeDetector( req.headers, supportedLocales, defaultLocale ); locale = detectedLocale; } rewriteUrl(req, res, originalPath, locale); return next(); }; const handlePrefix = ({ req, res, next, originalPath, pathLocale, cookieLocale }) => { if (!pathLocale) { handleMissingPathLocale({ req, res, next, originalPath, cookieLocale }); return; } handleExistingPathLocale({ req, res, next, originalPath, pathLocale, cookieLocale }); }; const handleMissingPathLocale = ({ req, res, next, originalPath, cookieLocale }) => { let locale = cookieLocale ?? localeDetector( req.headers, supportedLocales, defaultLocale ); if (!supportedLocales.includes(locale)) { locale = defaultLocale; } const newPath = constructPath(locale, originalPath); if (prefixDefault || locale !== defaultLocale) { return redirectUrl(res, newPath); } rewriteUrl(req, res, newPath, locale); return next(); }; const handleExistingPathLocale = ({ req, res, next, originalPath, pathLocale, cookieLocale }) => { if (cookieLocale && cookieLocale !== pathLocale && serverSetCookie !== "always") { const newPath = originalPath.replace(`/${pathLocale}`, `/${cookieLocale}`); const finalPath = constructPath(cookieLocale, newPath.replace(/^\/+/, "/")); return redirectUrl(res, finalPath); } handleDefaultLocaleRedirect({ req, res, next, originalPath, pathLocale }); }; const handleDefaultLocaleRedirect = ({ req, res, next, originalPath, pathLocale }) => { if (!prefixDefault && pathLocale === defaultLocale) { const newPath = originalPath.replace(`/${defaultLocale}`, "") ?? "/"; rewriteUrl(req, res, newPath, pathLocale); return next(); } rewriteUrl(req, res, originalPath, pathLocale); return next(); }; export { intLayerMiddlewarePlugin }; //# sourceMappingURL=intlayerMiddlewarePlugin.mjs.map