UNPKG

next-i18n-router

Version:

Next.js App Router internationalized routing and locale detection.

120 lines 4.94 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const localeDetector_1 = __importDefault(require("./localeDetector")); const validateConfig_1 = __importDefault(require("./validateConfig")); const server_1 = require("next/server"); function i18nRouter(request, config) { if (!request) { throw new Error(`i18nRouter requires a request argument.`); } if (!config) { throw new Error(`i18nRouter requires a config argument`); } const { locales, defaultLocale, localeCookie = 'NEXT_LOCALE', localeDetector = localeDetector_1.default, prefixDefault = false, basePath = '', serverSetCookie = 'always', noPrefix = false, cookieOptions = { path: request.nextUrl.basePath || undefined, sameSite: 'strict', maxAge: 31536000 // one year } } = config; (0, validateConfig_1.default)(config); const pathname = request.nextUrl.pathname; const basePathTrailingSlash = basePath.endsWith('/'); const responseOptions = { request: { headers: new Headers(request.headers) } }; let response = server_1.NextResponse.next(responseOptions); let cookieLocale; // check cookie for locale if (localeCookie) { const cookieValue = request.cookies.get(localeCookie)?.value; if (cookieValue && config.locales.includes(cookieValue)) { cookieLocale = cookieValue; } } const pathLocale = noPrefix ? undefined : locales.find(locale => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`); if (!pathLocale) { let locale = cookieLocale; // if no cookie, detect locale with localeDetector if (!locale) { if (localeDetector === false) { locale = defaultLocale; } else { locale = localeDetector(request, config); } } if (!locales.includes(locale)) { console.warn('The localeDetector callback must return a locale included in your locales array. Reverting to using defaultLocale.'); locale = defaultLocale; } let newPath = `${locale}${pathname}`; // this avoids double redirect: / => /en/ => /en if (pathname === '/') { newPath = newPath.slice(0, -1); } newPath = `${basePath}${basePathTrailingSlash ? '' : '/'}${newPath}`; if (request.nextUrl.search) { newPath += request.nextUrl.search; } if (noPrefix) { response = server_1.NextResponse.rewrite(new URL(newPath, request.url), responseOptions); } else if (prefixDefault || locale !== defaultLocale) { return server_1.NextResponse.redirect(new URL(newPath, request.url)); } else { // prefixDefault is false and using default locale response = server_1.NextResponse.rewrite(new URL(newPath, request.url), responseOptions); } } else { if (cookieLocale && cookieLocale !== pathLocale) { // if always, do not redirect to cookieLocale if (serverSetCookie !== 'always') { let newPath = pathname.replace(`/${pathLocale}`, `/${cookieLocale}`); if (request.nextUrl.search) { newPath += request.nextUrl.search; } if (basePathTrailingSlash) { newPath = newPath.slice(1); } newPath = `${basePath}${newPath}`; response = server_1.NextResponse.redirect(new URL(newPath, request.url)); } } // If /default, redirect to / if (!prefixDefault && pathLocale === defaultLocale) { let pathWithoutLocale = pathname.slice(`/${pathLocale}`.length) || '/'; if (basePathTrailingSlash) { pathWithoutLocale = pathWithoutLocale.slice(1); } if (request.nextUrl.search) { pathWithoutLocale += request.nextUrl.search; } response = server_1.NextResponse.redirect(new URL(`${basePath}${pathWithoutLocale}`, request.url)); } const setCookie = () => { response.cookies.set(localeCookie, pathLocale, cookieOptions); }; if (serverSetCookie !== 'never') { if (cookieLocale && cookieLocale !== pathLocale && serverSetCookie === 'always') { setCookie(); } else if (!cookieLocale) { setCookie(); } } } response.headers.set('x-next-i18n-router-locale', pathLocale || defaultLocale); return response; } exports.default = i18nRouter; //# sourceMappingURL=i18nRouter.js.map