gt-next 11.4.12 → 11.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/config-dir/props/withGTConfigProps.d.ts +2 -1
  3. package/dist/config-dir/props/withGTConfigProps.d.ts.map +1 -1
  4. package/dist/config-dir/props/withGTConfigProps.js.map +1 -1
  5. package/dist/config-dir/props/withGTConfigProps.mjs.map +1 -1
  6. package/dist/config.d.ts +7 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +11 -1
  9. package/dist/config.js.map +1 -1
  10. package/dist/config.mjs +11 -1
  11. package/dist/config.mjs.map +1 -1
  12. package/dist/errors/middleware.d.ts +2 -0
  13. package/dist/errors/middleware.d.ts.map +1 -1
  14. package/dist/errors/middleware.js +17 -0
  15. package/dist/errors/middleware.js.map +1 -1
  16. package/dist/errors/middleware.mjs +15 -1
  17. package/dist/errors/middleware.mjs.map +1 -1
  18. package/dist/gt_swc_plugin.wasm +0 -0
  19. package/dist/index.client.d.ts +1 -0
  20. package/dist/index.client.d.ts.map +1 -1
  21. package/dist/index.client.js +2 -0
  22. package/dist/index.client.js.map +1 -1
  23. package/dist/index.client.mjs +2 -1
  24. package/dist/index.client.mjs.map +1 -1
  25. package/dist/index.rsc.d.ts +1 -0
  26. package/dist/index.rsc.d.ts.map +1 -1
  27. package/dist/index.rsc.js +2 -0
  28. package/dist/index.rsc.js.map +1 -1
  29. package/dist/index.rsc.mjs +2 -1
  30. package/dist/index.rsc.mjs.map +1 -1
  31. package/dist/index.server.d.ts +1 -0
  32. package/dist/index.server.d.ts.map +1 -1
  33. package/dist/index.server.js +2 -0
  34. package/dist/index.server.js.map +1 -1
  35. package/dist/index.server.mjs +2 -1
  36. package/dist/index.server.mjs.map +1 -1
  37. package/dist/index.types.d.ts +11 -0
  38. package/dist/index.types.d.ts.map +1 -1
  39. package/dist/link/Link.d.ts +7 -4
  40. package/dist/link/Link.d.ts.map +1 -1
  41. package/dist/link/Link.js +19 -41
  42. package/dist/link/Link.js.map +1 -1
  43. package/dist/link/Link.mjs +19 -41
  44. package/dist/link/Link.mjs.map +1 -1
  45. package/dist/link/getLocalizeHref.d.ts +43 -0
  46. package/dist/link/getLocalizeHref.d.ts.map +1 -0
  47. package/dist/link/getLocalizeHref.js +59 -0
  48. package/dist/link/getLocalizeHref.js.map +1 -0
  49. package/dist/link/getLocalizeHref.mjs +56 -0
  50. package/dist/link/getLocalizeHref.mjs.map +1 -0
  51. package/dist/link/localize-utils.d.ts +15 -0
  52. package/dist/link/localize-utils.d.ts.map +1 -0
  53. package/dist/link/localize-utils.js +49 -0
  54. package/dist/link/localize-utils.js.map +1 -0
  55. package/dist/link/localize-utils.mjs +48 -0
  56. package/dist/link/localize-utils.mjs.map +1 -0
  57. package/dist/link/useLocalizeHref.d.ts +34 -0
  58. package/dist/link/useLocalizeHref.d.ts.map +1 -0
  59. package/dist/link/useLocalizeHref.js +46 -0
  60. package/dist/link/useLocalizeHref.js.map +1 -0
  61. package/dist/link/useLocalizeHref.mjs +44 -0
  62. package/dist/link/useLocalizeHref.mjs.map +1 -0
  63. package/dist/link.d.ts +2 -0
  64. package/dist/link.d.ts.map +1 -1
  65. package/dist/link.js +2 -0
  66. package/dist/link.mjs +2 -1
  67. package/dist/middleware-dir/createMiddlewareRouting.d.ts +7 -0
  68. package/dist/middleware-dir/createMiddlewareRouting.d.ts.map +1 -0
  69. package/dist/middleware-dir/createMiddlewareRouting.js +79 -0
  70. package/dist/middleware-dir/createMiddlewareRouting.js.map +1 -0
  71. package/dist/middleware-dir/createMiddlewareRouting.mjs +77 -0
  72. package/dist/middleware-dir/createMiddlewareRouting.mjs.map +1 -0
  73. package/dist/middleware-dir/createNextMiddleware.d.ts +5 -12
  74. package/dist/middleware-dir/createNextMiddleware.d.ts.map +1 -1
  75. package/dist/middleware-dir/createNextMiddleware.js +14 -55
  76. package/dist/middleware-dir/createNextMiddleware.js.map +1 -1
  77. package/dist/middleware-dir/createNextMiddleware.mjs +15 -56
  78. package/dist/middleware-dir/createNextMiddleware.mjs.map +1 -1
  79. package/dist/middleware-dir/defaultMiddlewareConfig.d.ts +11 -0
  80. package/dist/middleware-dir/defaultMiddlewareConfig.d.ts.map +1 -0
  81. package/dist/middleware-dir/defaultMiddlewareConfig.js +33 -0
  82. package/dist/middleware-dir/defaultMiddlewareConfig.js.map +1 -0
  83. package/dist/middleware-dir/defaultMiddlewareConfig.mjs +31 -0
  84. package/dist/middleware-dir/defaultMiddlewareConfig.mjs.map +1 -0
  85. package/dist/middleware-dir/resolveMiddlewareConfig.d.ts +9 -0
  86. package/dist/middleware-dir/resolveMiddlewareConfig.d.ts.map +1 -0
  87. package/dist/middleware-dir/resolveMiddlewareConfig.js +32 -0
  88. package/dist/middleware-dir/resolveMiddlewareConfig.js.map +1 -0
  89. package/dist/middleware-dir/resolveMiddlewareConfig.mjs +30 -0
  90. package/dist/middleware-dir/resolveMiddlewareConfig.mjs.map +1 -0
  91. package/dist/middleware-dir/types.d.ts +56 -0
  92. package/dist/middleware-dir/types.d.ts.map +1 -0
  93. package/dist/middleware-dir/types.js +1 -0
  94. package/dist/middleware-dir/types.mjs +1 -0
  95. package/dist/server.d.ts +1 -0
  96. package/dist/server.d.ts.map +1 -1
  97. package/dist/server.js +2 -0
  98. package/dist/server.js.map +1 -1
  99. package/dist/server.mjs +2 -1
  100. package/dist/server.mjs.map +1 -1
  101. package/dist/utils/client-boundary.js +1 -1
  102. package/dist/utils/client-boundary.mjs +1 -1
  103. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"createNextMiddleware.js","names":["compilePathRegex","GTRuntime","libraryDefaultLocale","defaultLocaleCookieName","defaultResetLocaleCookieName","createUnsupportedLocalesWarning","createPathToSharedPathMap","createPathMatcher","pathnameMatchesRegex","NextResponse","getLocaleFromRequest","getResponse","getSharedPath","replaceDynamicSegments","getLocalizedPath","applyTrailingSlash","normalizePathname"],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { applyTrailingSlash } from './pathname';\nimport { GTRuntime } from 'generaltranslation/runtime';\nimport { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { createUnsupportedLocalesWarning } from '../errors/middleware';\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from '../utils/cookies';\nimport {\n defaultLocaleCookieName,\n defaultResetLocaleCookieName,\n} from '@generaltranslation/react-core/pure';\nimport {\n normalizePathname,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n createPathToSharedPathMap,\n createPathMatcher,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n type PathConfig,\n type PathMatcher,\n} from './utils';\nimport { defaultLocaleHeaderName } from '../utils/headers';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport type { HeadersAndCookies } from '../config-dir/props/withGTConfigProps';\nimport { compilePathRegex, pathnameMatchesRegex } from '../utils/pathRegex';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\ntype MiddlewareEnvConfig = {\n customMapping?: CustomMapping;\n defaultLocale?: string;\n locales?: string[];\n headersAndCookies?: HeadersAndCookies;\n};\n\nexport type RouteOverrides = Record<string, readonly string[]>;\n\nexport type LocaleRoutes = Record<string, readonly string[]>;\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.enableSmartRouting=true] - Keep automatic locale negotiation. Disable to treat returning visitors' unprefixed URLs as default-locale routes.\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @param {RouteOverrides} [config.routeOverrides] - Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}\n * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware({\n localeRouting = true,\n prefixDefaultLocale = false,\n enableSmartRouting = true,\n ignoreSourceMaps = true,\n pathConfig = {},\n routeOverrides = {},\n localeRoutes = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: boolean;\n enableSmartRouting?: boolean;\n ignoreSourceMaps?: boolean;\n pathConfig?: PathConfig;\n routeOverrides?: RouteOverrides;\n localeRoutes?: LocaleRoutes;\n} = {}) {\n const pathRegex = compilePathRegex(\n process.env._GENERALTRANSLATION_PATH_REGEX\n );\n\n // i18n config\n let envParams: MiddlewareEnvConfig | undefined;\n if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) {\n try {\n envParams = JSON.parse(\n process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS\n );\n } catch (error) {\n console.error(`gt-next middleware:`, error);\n }\n }\n\n // gt instance\n const gt = new GTRuntime({\n customMapping: envParams?.customMapping,\n });\n\n // Configured spellings are the identity used by routes, cookies and caches.\n const defaultLocale: string =\n envParams?.defaultLocale || libraryDefaultLocale;\n const locales = Array.from(\n new Set([defaultLocale, ...(envParams?.locales || [])])\n );\n // Route entries repeat locale keys. Resolve each key once per factory instead\n // of rebuilding the full locale-resolution index for every route/locale pair.\n const resolvedConfigLocales = new Map<string, string>();\n const determineLocaleWithCache = (locale: string) => {\n const cached = resolvedConfigLocales.get(locale);\n if (cached !== undefined) return cached;\n const resolved = gt.determineLocale(locale, locales) ?? locale;\n resolvedConfigLocales.set(locale, resolved);\n return resolved;\n };\n const resolvePathConfigLocale =\n process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === 'true'\n ? determineLocaleWithCache\n : (locale: string) => locale;\n\n // cookies and header names\n const headersAndCookies = envParams?.headersAndCookies || {};\n const localeRoutingEnabledCookieName =\n headersAndCookies?.localeRoutingEnabledCookieName ||\n defaultLocaleRoutingEnabledCookieName;\n const referrerLocaleCookieName =\n headersAndCookies?.referrerLocaleCookieName ||\n defaultReferrerLocaleCookieName;\n const localeCookieName =\n headersAndCookies?.localeCookieName || defaultLocaleCookieName;\n const resetLocaleCookieName =\n headersAndCookies?.resetLocaleCookieName || defaultResetLocaleCookieName;\n const localeHeaderName =\n headersAndCookies?.localeHeaderName || defaultLocaleHeaderName;\n\n if (!gt.isValidLocale(defaultLocale))\n throw new Error(\n `gt-next middleware: defaultLocale \"${defaultLocale}\" is not a valid locale.`\n );\n\n const warningLocales = locales.filter((locale) => !gt.isValidLocale(locale));\n if (warningLocales.length)\n console.warn(createUnsupportedLocalesWarning(warningLocales));\n\n // ---------- PRE-PROCESSING PATHS ---------- //\n\n // --- localized routes --- //\n // Resolve pathConfig keys to the configured locale spelling.\n pathConfig = Object.entries(pathConfig).reduce<PathConfig>(\n (acc, [sharedPath, localizedPath]) => {\n if (typeof localizedPath === 'string') {\n acc[sharedPath] = localizedPath;\n } else {\n acc[sharedPath] = Object.entries(localizedPath).reduce<{\n [key: string]: string;\n }>((acc, [locale, localizedPath]) => {\n acc[resolvePathConfigLocale(locale)] = localizedPath;\n return acc;\n }, {});\n }\n return acc;\n },\n {}\n );\n\n // String aliases apply to every locale, including the default locale.\n // Expand a copy for lookup while retaining string target semantics in routing.\n const matcherPathConfig = Object.fromEntries(\n Object.entries(pathConfig).map(([sharedPath, localizedPath]) => [\n sharedPath,\n typeof localizedPath === 'string'\n ? Object.fromEntries(\n locales.map((locale) => [\n determineLocaleWithCache(locale),\n localizedPath === '' ? '/' : localizedPath,\n ])\n )\n : localizedPath,\n ])\n );\n\n // Create the path mapping\n const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(\n matcherPathConfig,\n prefixDefaultLocale,\n defaultLocale\n );\n\n // --- route overrides --- //\n // Resolve routeOverrides keys to the configured locale spelling.\n routeOverrides = Object.entries(routeOverrides).reduce<RouteOverrides>(\n (acc, [locale, paths]) => {\n acc[resolvePathConfigLocale(locale)] = paths;\n return acc;\n },\n {}\n );\n\n // Create the route override path mapping\n const routeOverridePathMaps = Object.entries(routeOverrides).reduce<\n Record<string, PathMatcher>\n >((acc, [locale, paths]) => {\n const overridePathConfig = Object.fromEntries(\n paths.map((path) => [path, path])\n );\n acc[locale] = createPathToSharedPathMap(\n overridePathConfig,\n true,\n defaultLocale\n ).pathToSharedPath;\n return acc;\n }, {});\n\n // --- locale routes --- //\n // Compile availability separately from aliases and overrides so it cannot\n // change route precedence. An empty list deliberately matches nothing.\n const localeRoutePathMaps = new Map(\n Object.entries(localeRoutes).map(([locale, paths]) => {\n // Match request resolution so equivalent spellings use the same map key.\n const resolvedLocale = determineLocaleWithCache(locale);\n return [\n resolvedLocale,\n createPathMatcher(paths.map((path) => [path, path])),\n ];\n })\n );\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale: requestedLocale,\n pathnameLocale: pathnameRoutingLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt,\n enableSmartRouting\n );\n\n let userLocale = requestedLocale;\n const pathnameLocale = pathnameRoutingLocale;\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) => {\n const response = getResponse({\n responsePath,\n type: 'redirect',\n ...responseConfig,\n });\n if (\n !enableSmartRouting &&\n !prefixDefaultLocale &&\n pathnameLocale === defaultLocale &&\n userLocale === defaultLocale &&\n req.headers.get('sec-fetch-dest') === 'document' &&\n !req.cookies.has(localeCookieName)\n ) {\n // Preserve explicit /en intent across a first document redirect.\n // Background fetches and returning visits must not change the cookie.\n response.cookies.set(localeCookieName, defaultLocale);\n }\n return response;\n };\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${pathnameLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPathMatch = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n const sharedPath = sharedPathMatch?.sharedPath;\n\n // Return early for a locale route that does not exist\n const localeRoutePathMap = localeRoutePathMaps.get(userLocale);\n if (userLocale !== defaultLocale && localeRoutePathMap) {\n // Resolve the shared page path without a locale prefix (e.g. /blog/hello).\n // Strip the URL's locale, which may differ from the newly selected locale.\n const sharedPagePath = sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n sharedPath || '/',\n sharedPathMatch.pathTemplate\n )\n : (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname) || '/';\n\n // If the path does not exist, redirect to the default locale path\n if (\n getSharedPath(sharedPagePath, localeRoutePathMap, undefined) ===\n undefined\n ) {\n // Get the path to redirect to\n const defaultPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, defaultLocale, pathConfig)\n : undefined;\n const fallbackPath =\n defaultPath !== undefined && sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n defaultPath,\n sharedPathMatch.pathTemplate\n )\n : `/${defaultLocale}${sharedPagePath === '/' ? '' : sharedPagePath}`;\n const publicFallbackPath = applyTrailingSlash(\n standardizedPathname,\n prefixDefaultLocale\n ? fallbackPath\n : fallbackPath.slice(defaultLocale.length + 1) || '/'\n );\n\n // The default locale is terminal, even if the preference/reset cookie\n // still requests an unavailable locale on the redirected request.\n userLocale = defaultLocale;\n responseConfig.userLocale = defaultLocale;\n const fallbackUrl = new URL(req.nextUrl);\n fallbackUrl.pathname = publicFallbackPath;\n if (fallbackUrl.pathname !== pathname) {\n return getRedirectResponse(publicFallbackPath);\n }\n // Already at the fallback URL: use normal default-locale routing below,\n // including its alias/override rewrite, instead of redirecting to itself.\n }\n }\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n `/${userLocale}${sharedPath}`,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined && sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n localizedPath,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n const pagePath =\n (sharedPathWithParameters?.slice(userLocale.length + 1) ??\n (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname)) ||\n '/';\n const routeOverridePathMap = routeOverridePathMaps[userLocale];\n const routeOverrideMatch = routeOverridePathMap\n ? getSharedPath(pagePath, routeOverridePathMap, undefined)\n : undefined;\n const routeOverridePath =\n routeOverrideMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n `/${userLocale}/${userLocale}${pagePath === '/' ? '' : pagePath}`\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/customers -> /customers)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n pathname.slice(\n (unstandardizedPathnameLocale as string).length + 1\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(\n routeOverridePath || `/${userLocale}${pathname}`\n );\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/blog -> /blog)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n localizedPathWithParameters.slice(userLocale.length + 1) || '/'\n );\n }\n } else {\n const localizedPublicPath =\n localizedPathWithParameters.slice(userLocale.length + 1) || '/';\n\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n normalizePathname(localizedPublicPath) !==\n normalizePathname(pathname)\n ) {\n return getRedirectResponse(localizedPublicPath);\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(\n routeOverridePath || (sharedPathWithParameters as string)\n );\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (\n normalizePathname(pathname) !==\n normalizePathname(localizedPathWithParameters)\n ) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n // Next.js route identity preserves Unicode spelling, even when lookup\n // considers the public alias and shared path canonically equivalent.\n const rewriteUrl = new URL(\n sharedPathWithParameters as string,\n req.nextUrl\n );\n if (\n req.nextUrl.pathname !== rewriteUrl.pathname // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createNextMiddleware.js","names":["resolveMiddlewareConfig","createLinkRoutingConfigMismatchWarning","createMiddlewareRouting","pathnameMatchesRegex","NextResponse","getLocaleFromRequest","getResponse","getSharedPath","replaceDynamicSegments","getLocalizedPath","applyTrailingSlash","normalizePathname"],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { applyTrailingSlash } from './pathname';\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport {\n normalizePathname,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n} from './utils';\nimport { pathnameMatchesRegex } from '../utils/pathRegex';\nimport { createMiddlewareRouting } from './createMiddlewareRouting';\nimport { resolveMiddlewareConfig } from './resolveMiddlewareConfig';\nimport type { MiddlewareConfig } from './types';\nimport { createLinkRoutingConfigMismatchWarning } from '../errors/middleware';\n\nexport type { RouteOverrides, LocaleRoutes } from './types';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\n// Options gt-next/link reads from withGTConfig() to avoid redirects.\nconst LINK_ROUTING_OPTIONS = [\n 'prefixDefaultLocale',\n 'enableSmartRouting',\n] as const;\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * Options omitted here fall back to the same options passed to `withGTConfig()`.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.enableSmartRouting=true] - Keep automatic locale negotiation. Disable to treat returning visitors' unprefixed URLs as default-locale routes.\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @param {RouteOverrides} [config.routeOverrides] - Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}\n * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware(options: MiddlewareConfig = {}) {\n const config = resolveMiddlewareConfig(options);\n if (process.env.NODE_ENV === 'development') {\n const linkConfig = resolveMiddlewareConfig();\n const mismatches = LINK_ROUTING_OPTIONS.filter(\n (option) => config[option] !== linkConfig[option]\n );\n if (mismatches.length)\n console.warn(createLinkRoutingConfigMismatchWarning(mismatches));\n }\n const {\n localeRouting,\n prefixDefaultLocale,\n enableSmartRouting,\n ignoreSourceMaps,\n } = config;\n const {\n pathRegex,\n gt,\n defaultLocale,\n locales,\n localeRoutingEnabledCookieName,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n pathConfig,\n pathToSharedPath,\n defaultLocalePaths,\n routeOverridePathMaps,\n localeRoutePathMaps,\n } = createMiddlewareRouting(config);\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale: requestedLocale,\n pathnameLocale: pathnameRoutingLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt,\n enableSmartRouting\n );\n\n let userLocale = requestedLocale;\n const pathnameLocale = pathnameRoutingLocale;\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) => {\n const response = getResponse({\n responsePath,\n type: 'redirect',\n ...responseConfig,\n });\n if (\n !enableSmartRouting &&\n !prefixDefaultLocale &&\n pathnameLocale === defaultLocale &&\n userLocale === defaultLocale &&\n req.headers.get('sec-fetch-dest') === 'document' &&\n !req.cookies.has(localeCookieName)\n ) {\n // Preserve explicit /en intent across a first document redirect.\n // Background fetches and returning visits must not change the cookie.\n response.cookies.set(localeCookieName, defaultLocale);\n }\n return response;\n };\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${pathnameLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPathMatch = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n const sharedPath = sharedPathMatch?.sharedPath;\n\n // Return early for a locale route that does not exist\n const localeRoutePathMap = localeRoutePathMaps.get(userLocale);\n if (userLocale !== defaultLocale && localeRoutePathMap) {\n // Resolve the shared page path without a locale prefix (e.g. /blog/hello).\n // Strip the URL's locale, which may differ from the newly selected locale.\n const sharedPagePath = sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n sharedPath || '/',\n sharedPathMatch.pathTemplate\n )\n : (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname) || '/';\n\n // If the path does not exist, redirect to the default locale path\n if (\n getSharedPath(sharedPagePath, localeRoutePathMap, undefined) ===\n undefined\n ) {\n // Get the path to redirect to\n const defaultPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, defaultLocale, pathConfig)\n : undefined;\n const fallbackPath =\n defaultPath !== undefined && sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n defaultPath,\n sharedPathMatch.pathTemplate\n )\n : `/${defaultLocale}${sharedPagePath === '/' ? '' : sharedPagePath}`;\n const publicFallbackPath = applyTrailingSlash(\n standardizedPathname,\n prefixDefaultLocale\n ? fallbackPath\n : fallbackPath.slice(defaultLocale.length + 1) || '/'\n );\n\n // The default locale is terminal, even if the preference/reset cookie\n // still requests an unavailable locale on the redirected request.\n userLocale = defaultLocale;\n responseConfig.userLocale = defaultLocale;\n const fallbackUrl = new URL(req.nextUrl);\n fallbackUrl.pathname = publicFallbackPath;\n if (fallbackUrl.pathname !== pathname) {\n return getRedirectResponse(publicFallbackPath);\n }\n // Already at the fallback URL: use normal default-locale routing below,\n // including its alias/override rewrite, instead of redirecting to itself.\n }\n }\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n `/${userLocale}${sharedPath}`,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined && sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n localizedPath,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n const pagePath =\n (sharedPathWithParameters?.slice(userLocale.length + 1) ??\n (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname)) ||\n '/';\n const routeOverridePathMap = routeOverridePathMaps[userLocale];\n const routeOverrideMatch = routeOverridePathMap\n ? getSharedPath(pagePath, routeOverridePathMap, undefined)\n : undefined;\n const routeOverridePath =\n routeOverrideMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n `/${userLocale}/${userLocale}${pagePath === '/' ? '' : pagePath}`\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/customers -> /customers)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n pathname.slice(\n (unstandardizedPathnameLocale as string).length + 1\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(\n routeOverridePath || `/${userLocale}${pathname}`\n );\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/blog -> /blog)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n localizedPathWithParameters.slice(userLocale.length + 1) || '/'\n );\n }\n } else {\n const localizedPublicPath =\n localizedPathWithParameters.slice(userLocale.length + 1) || '/';\n\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n normalizePathname(localizedPublicPath) !==\n normalizePathname(pathname)\n ) {\n return getRedirectResponse(localizedPublicPath);\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(\n routeOverridePath || (sharedPathWithParameters as string)\n );\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (\n normalizePathname(pathname) !==\n normalizePathname(localizedPathWithParameters)\n ) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n // Next.js route identity preserves Unicode spelling, even when lookup\n // considers the public alias and shared path canonically equivalent.\n const rewriteUrl = new URL(\n sharedPathWithParameters as string,\n req.nextUrl\n );\n if (\n req.nextUrl.pathname !== rewriteUrl.pathname // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
@@ -1,17 +1,14 @@
1
- import "../utils/headers.mjs";
2
- import "../utils/cookies.mjs";
3
- import { compilePathRegex, pathnameMatchesRegex } from "../utils/pathRegex.mjs";
1
+ import { pathnameMatchesRegex } from "../utils/pathRegex.mjs";
2
+ import { createLinkRoutingConfigMismatchWarning } from "../errors/middleware.mjs";
3
+ import { resolveMiddlewareConfig } from "./resolveMiddlewareConfig.mjs";
4
4
  import { applyTrailingSlash, normalizePathname } from "./pathname.mjs";
5
- import { createUnsupportedLocalesWarning } from "../errors/middleware.mjs";
6
- import { createPathMatcher, createPathToSharedPathMap } from "./createPathMatcher.mjs";
7
5
  import { getSharedPath } from "./matchPath.mjs";
8
6
  import { getLocaleFromRequest, getLocalizedPath, getResponse, replaceDynamicSegments } from "./utils.mjs";
9
- import { libraryDefaultLocale } from "generaltranslation/internal";
10
- import { defaultLocaleCookieName, defaultResetLocaleCookieName } from "@generaltranslation/react-core/pure";
11
- import { GTRuntime } from "generaltranslation/runtime";
7
+ import { createMiddlewareRouting } from "./createMiddlewareRouting.mjs";
12
8
  import { NextResponse } from "next/server.js";
13
9
  //#region src/middleware-dir/createNextMiddleware.ts
14
10
  const NEXT_JS_SOURCE_MAP_PATH = "/__nextjs_source-map";
11
+ const LINK_ROUTING_OPTIONS = ["prefixDefaultLocale", "enableSmartRouting"];
15
12
  /**
16
13
  * Middleware factory to create a Next.js middleware for i18n routing and locale detection.
17
14
  *
@@ -20,6 +17,8 @@ const NEXT_JS_SOURCE_MAP_PATH = "/__nextjs_source-map";
20
17
  * If locale routing is enabled, it redirects to the localized pathname and
21
18
  * updates the locale cookie.
22
19
  *
20
+ * Options omitted here fall back to the same options passed to `withGTConfig()`.
21
+ *
23
22
  * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.
24
23
  * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about
25
24
  * @param {boolean} [config.enableSmartRouting=true] - Keep automatic locale negotiation. Disable to treat returning visitors' unprefixed URLs as default-locale routes.
@@ -29,55 +28,15 @@ const NEXT_JS_SOURCE_MAP_PATH = "/__nextjs_source-map";
29
28
  * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale
30
29
  * @returns {function} - A middleware function that processes the request and response.
31
30
  */
32
- function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, enableSmartRouting = true, ignoreSourceMaps = true, pathConfig = {}, routeOverrides = {}, localeRoutes = {} } = {}) {
33
- const pathRegex = compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);
34
- let envParams;
35
- if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) try {
36
- envParams = JSON.parse(process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS);
37
- } catch (error) {
38
- console.error(`gt-next middleware:`, error);
31
+ function createNextMiddleware(options = {}) {
32
+ const config = resolveMiddlewareConfig(options);
33
+ if (process.env.NODE_ENV === "development") {
34
+ const linkConfig = resolveMiddlewareConfig();
35
+ const mismatches = LINK_ROUTING_OPTIONS.filter((option) => config[option] !== linkConfig[option]);
36
+ if (mismatches.length) console.warn(createLinkRoutingConfigMismatchWarning(mismatches));
39
37
  }
40
- const gt = new GTRuntime({ customMapping: envParams?.customMapping });
41
- const defaultLocale = envParams?.defaultLocale || libraryDefaultLocale;
42
- const locales = Array.from(new Set([defaultLocale, ...envParams?.locales || []]));
43
- const resolvedConfigLocales = /* @__PURE__ */ new Map();
44
- const determineLocaleWithCache = (locale) => {
45
- const cached = resolvedConfigLocales.get(locale);
46
- if (cached !== void 0) return cached;
47
- const resolved = gt.determineLocale(locale, locales) ?? locale;
48
- resolvedConfigLocales.set(locale, resolved);
49
- return resolved;
50
- };
51
- const resolvePathConfigLocale = process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === "true" ? determineLocaleWithCache : (locale) => locale;
52
- const headersAndCookies = envParams?.headersAndCookies || {};
53
- const localeRoutingEnabledCookieName = headersAndCookies?.localeRoutingEnabledCookieName || "generaltranslation.locale-routing-enabled";
54
- const referrerLocaleCookieName = headersAndCookies?.referrerLocaleCookieName || "generaltranslation.referrer-locale";
55
- const localeCookieName = headersAndCookies?.localeCookieName || defaultLocaleCookieName;
56
- const resetLocaleCookieName = headersAndCookies?.resetLocaleCookieName || defaultResetLocaleCookieName;
57
- const localeHeaderName = headersAndCookies?.localeHeaderName || "x-generaltranslation-locale";
58
- if (!gt.isValidLocale(defaultLocale)) throw new Error(`gt-next middleware: defaultLocale "${defaultLocale}" is not a valid locale.`);
59
- const warningLocales = locales.filter((locale) => !gt.isValidLocale(locale));
60
- if (warningLocales.length) console.warn(createUnsupportedLocalesWarning(warningLocales));
61
- pathConfig = Object.entries(pathConfig).reduce((acc, [sharedPath, localizedPath]) => {
62
- if (typeof localizedPath === "string") acc[sharedPath] = localizedPath;
63
- else acc[sharedPath] = Object.entries(localizedPath).reduce((acc, [locale, localizedPath]) => {
64
- acc[resolvePathConfigLocale(locale)] = localizedPath;
65
- return acc;
66
- }, {});
67
- return acc;
68
- }, {});
69
- const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(Object.fromEntries(Object.entries(pathConfig).map(([sharedPath, localizedPath]) => [sharedPath, typeof localizedPath === "string" ? Object.fromEntries(locales.map((locale) => [determineLocaleWithCache(locale), localizedPath === "" ? "/" : localizedPath])) : localizedPath])), prefixDefaultLocale, defaultLocale);
70
- routeOverrides = Object.entries(routeOverrides).reduce((acc, [locale, paths]) => {
71
- acc[resolvePathConfigLocale(locale)] = paths;
72
- return acc;
73
- }, {});
74
- const routeOverridePathMaps = Object.entries(routeOverrides).reduce((acc, [locale, paths]) => {
75
- acc[locale] = createPathToSharedPathMap(Object.fromEntries(paths.map((path) => [path, path])), true, defaultLocale).pathToSharedPath;
76
- return acc;
77
- }, {});
78
- const localeRoutePathMaps = new Map(Object.entries(localeRoutes).map(([locale, paths]) => {
79
- return [determineLocaleWithCache(locale), createPathMatcher(paths.map((path) => [path, path]))];
80
- }));
38
+ const { localeRouting, prefixDefaultLocale, enableSmartRouting, ignoreSourceMaps } = config;
39
+ const { pathRegex, gt, defaultLocale, locales, localeRoutingEnabledCookieName, referrerLocaleCookieName, localeCookieName, resetLocaleCookieName, localeHeaderName, pathConfig, pathToSharedPath, defaultLocalePaths, routeOverridePathMaps, localeRoutePathMaps } = createMiddlewareRouting(config);
81
40
  /**
82
41
  * Processes the incoming request to determine the user's locale and sets a locale cookie.
83
42
  * Optionally redirects the user based on the locale if locale-based routing is enabled.
@@ -1 +1 @@
1
- {"version":3,"file":"createNextMiddleware.mjs","names":[],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { applyTrailingSlash } from './pathname';\nimport { GTRuntime } from 'generaltranslation/runtime';\nimport { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { createUnsupportedLocalesWarning } from '../errors/middleware';\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport {\n defaultLocaleRoutingEnabledCookieName,\n defaultReferrerLocaleCookieName,\n} from '../utils/cookies';\nimport {\n defaultLocaleCookieName,\n defaultResetLocaleCookieName,\n} from '@generaltranslation/react-core/pure';\nimport {\n normalizePathname,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n createPathToSharedPathMap,\n createPathMatcher,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n type PathConfig,\n type PathMatcher,\n} from './utils';\nimport { defaultLocaleHeaderName } from '../utils/headers';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport type { HeadersAndCookies } from '../config-dir/props/withGTConfigProps';\nimport { compilePathRegex, pathnameMatchesRegex } from '../utils/pathRegex';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\ntype MiddlewareEnvConfig = {\n customMapping?: CustomMapping;\n defaultLocale?: string;\n locales?: string[];\n headersAndCookies?: HeadersAndCookies;\n};\n\nexport type RouteOverrides = Record<string, readonly string[]>;\n\nexport type LocaleRoutes = Record<string, readonly string[]>;\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.enableSmartRouting=true] - Keep automatic locale negotiation. Disable to treat returning visitors' unprefixed URLs as default-locale routes.\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @param {RouteOverrides} [config.routeOverrides] - Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}\n * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware({\n localeRouting = true,\n prefixDefaultLocale = false,\n enableSmartRouting = true,\n ignoreSourceMaps = true,\n pathConfig = {},\n routeOverrides = {},\n localeRoutes = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: boolean;\n enableSmartRouting?: boolean;\n ignoreSourceMaps?: boolean;\n pathConfig?: PathConfig;\n routeOverrides?: RouteOverrides;\n localeRoutes?: LocaleRoutes;\n} = {}) {\n const pathRegex = compilePathRegex(\n process.env._GENERALTRANSLATION_PATH_REGEX\n );\n\n // i18n config\n let envParams: MiddlewareEnvConfig | undefined;\n if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) {\n try {\n envParams = JSON.parse(\n process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS\n );\n } catch (error) {\n console.error(`gt-next middleware:`, error);\n }\n }\n\n // gt instance\n const gt = new GTRuntime({\n customMapping: envParams?.customMapping,\n });\n\n // Configured spellings are the identity used by routes, cookies and caches.\n const defaultLocale: string =\n envParams?.defaultLocale || libraryDefaultLocale;\n const locales = Array.from(\n new Set([defaultLocale, ...(envParams?.locales || [])])\n );\n // Route entries repeat locale keys. Resolve each key once per factory instead\n // of rebuilding the full locale-resolution index for every route/locale pair.\n const resolvedConfigLocales = new Map<string, string>();\n const determineLocaleWithCache = (locale: string) => {\n const cached = resolvedConfigLocales.get(locale);\n if (cached !== undefined) return cached;\n const resolved = gt.determineLocale(locale, locales) ?? locale;\n resolvedConfigLocales.set(locale, resolved);\n return resolved;\n };\n const resolvePathConfigLocale =\n process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === 'true'\n ? determineLocaleWithCache\n : (locale: string) => locale;\n\n // cookies and header names\n const headersAndCookies = envParams?.headersAndCookies || {};\n const localeRoutingEnabledCookieName =\n headersAndCookies?.localeRoutingEnabledCookieName ||\n defaultLocaleRoutingEnabledCookieName;\n const referrerLocaleCookieName =\n headersAndCookies?.referrerLocaleCookieName ||\n defaultReferrerLocaleCookieName;\n const localeCookieName =\n headersAndCookies?.localeCookieName || defaultLocaleCookieName;\n const resetLocaleCookieName =\n headersAndCookies?.resetLocaleCookieName || defaultResetLocaleCookieName;\n const localeHeaderName =\n headersAndCookies?.localeHeaderName || defaultLocaleHeaderName;\n\n if (!gt.isValidLocale(defaultLocale))\n throw new Error(\n `gt-next middleware: defaultLocale \"${defaultLocale}\" is not a valid locale.`\n );\n\n const warningLocales = locales.filter((locale) => !gt.isValidLocale(locale));\n if (warningLocales.length)\n console.warn(createUnsupportedLocalesWarning(warningLocales));\n\n // ---------- PRE-PROCESSING PATHS ---------- //\n\n // --- localized routes --- //\n // Resolve pathConfig keys to the configured locale spelling.\n pathConfig = Object.entries(pathConfig).reduce<PathConfig>(\n (acc, [sharedPath, localizedPath]) => {\n if (typeof localizedPath === 'string') {\n acc[sharedPath] = localizedPath;\n } else {\n acc[sharedPath] = Object.entries(localizedPath).reduce<{\n [key: string]: string;\n }>((acc, [locale, localizedPath]) => {\n acc[resolvePathConfigLocale(locale)] = localizedPath;\n return acc;\n }, {});\n }\n return acc;\n },\n {}\n );\n\n // String aliases apply to every locale, including the default locale.\n // Expand a copy for lookup while retaining string target semantics in routing.\n const matcherPathConfig = Object.fromEntries(\n Object.entries(pathConfig).map(([sharedPath, localizedPath]) => [\n sharedPath,\n typeof localizedPath === 'string'\n ? Object.fromEntries(\n locales.map((locale) => [\n determineLocaleWithCache(locale),\n localizedPath === '' ? '/' : localizedPath,\n ])\n )\n : localizedPath,\n ])\n );\n\n // Create the path mapping\n const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(\n matcherPathConfig,\n prefixDefaultLocale,\n defaultLocale\n );\n\n // --- route overrides --- //\n // Resolve routeOverrides keys to the configured locale spelling.\n routeOverrides = Object.entries(routeOverrides).reduce<RouteOverrides>(\n (acc, [locale, paths]) => {\n acc[resolvePathConfigLocale(locale)] = paths;\n return acc;\n },\n {}\n );\n\n // Create the route override path mapping\n const routeOverridePathMaps = Object.entries(routeOverrides).reduce<\n Record<string, PathMatcher>\n >((acc, [locale, paths]) => {\n const overridePathConfig = Object.fromEntries(\n paths.map((path) => [path, path])\n );\n acc[locale] = createPathToSharedPathMap(\n overridePathConfig,\n true,\n defaultLocale\n ).pathToSharedPath;\n return acc;\n }, {});\n\n // --- locale routes --- //\n // Compile availability separately from aliases and overrides so it cannot\n // change route precedence. An empty list deliberately matches nothing.\n const localeRoutePathMaps = new Map(\n Object.entries(localeRoutes).map(([locale, paths]) => {\n // Match request resolution so equivalent spellings use the same map key.\n const resolvedLocale = determineLocaleWithCache(locale);\n return [\n resolvedLocale,\n createPathMatcher(paths.map((path) => [path, path])),\n ];\n })\n );\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale: requestedLocale,\n pathnameLocale: pathnameRoutingLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt,\n enableSmartRouting\n );\n\n let userLocale = requestedLocale;\n const pathnameLocale = pathnameRoutingLocale;\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) => {\n const response = getResponse({\n responsePath,\n type: 'redirect',\n ...responseConfig,\n });\n if (\n !enableSmartRouting &&\n !prefixDefaultLocale &&\n pathnameLocale === defaultLocale &&\n userLocale === defaultLocale &&\n req.headers.get('sec-fetch-dest') === 'document' &&\n !req.cookies.has(localeCookieName)\n ) {\n // Preserve explicit /en intent across a first document redirect.\n // Background fetches and returning visits must not change the cookie.\n response.cookies.set(localeCookieName, defaultLocale);\n }\n return response;\n };\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${pathnameLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPathMatch = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n const sharedPath = sharedPathMatch?.sharedPath;\n\n // Return early for a locale route that does not exist\n const localeRoutePathMap = localeRoutePathMaps.get(userLocale);\n if (userLocale !== defaultLocale && localeRoutePathMap) {\n // Resolve the shared page path without a locale prefix (e.g. /blog/hello).\n // Strip the URL's locale, which may differ from the newly selected locale.\n const sharedPagePath = sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n sharedPath || '/',\n sharedPathMatch.pathTemplate\n )\n : (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname) || '/';\n\n // If the path does not exist, redirect to the default locale path\n if (\n getSharedPath(sharedPagePath, localeRoutePathMap, undefined) ===\n undefined\n ) {\n // Get the path to redirect to\n const defaultPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, defaultLocale, pathConfig)\n : undefined;\n const fallbackPath =\n defaultPath !== undefined && sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n defaultPath,\n sharedPathMatch.pathTemplate\n )\n : `/${defaultLocale}${sharedPagePath === '/' ? '' : sharedPagePath}`;\n const publicFallbackPath = applyTrailingSlash(\n standardizedPathname,\n prefixDefaultLocale\n ? fallbackPath\n : fallbackPath.slice(defaultLocale.length + 1) || '/'\n );\n\n // The default locale is terminal, even if the preference/reset cookie\n // still requests an unavailable locale on the redirected request.\n userLocale = defaultLocale;\n responseConfig.userLocale = defaultLocale;\n const fallbackUrl = new URL(req.nextUrl);\n fallbackUrl.pathname = publicFallbackPath;\n if (fallbackUrl.pathname !== pathname) {\n return getRedirectResponse(publicFallbackPath);\n }\n // Already at the fallback URL: use normal default-locale routing below,\n // including its alias/override rewrite, instead of redirecting to itself.\n }\n }\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n `/${userLocale}${sharedPath}`,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined && sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n localizedPath,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n const pagePath =\n (sharedPathWithParameters?.slice(userLocale.length + 1) ??\n (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname)) ||\n '/';\n const routeOverridePathMap = routeOverridePathMaps[userLocale];\n const routeOverrideMatch = routeOverridePathMap\n ? getSharedPath(pagePath, routeOverridePathMap, undefined)\n : undefined;\n const routeOverridePath =\n routeOverrideMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n `/${userLocale}/${userLocale}${pagePath === '/' ? '' : pagePath}`\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/customers -> /customers)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n pathname.slice(\n (unstandardizedPathnameLocale as string).length + 1\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(\n routeOverridePath || `/${userLocale}${pathname}`\n );\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/blog -> /blog)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n localizedPathWithParameters.slice(userLocale.length + 1) || '/'\n );\n }\n } else {\n const localizedPublicPath =\n localizedPathWithParameters.slice(userLocale.length + 1) || '/';\n\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n normalizePathname(localizedPublicPath) !==\n normalizePathname(pathname)\n ) {\n return getRedirectResponse(localizedPublicPath);\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(\n routeOverridePath || (sharedPathWithParameters as string)\n );\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (\n normalizePathname(pathname) !==\n normalizePathname(localizedPathWithParameters)\n ) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n // Next.js route identity preserves Unicode spelling, even when lookup\n // considers the public alias and shared path canonically equivalent.\n const rewriteUrl = new URL(\n sharedPathWithParameters as string,\n req.nextUrl\n );\n if (\n req.nextUrl.pathname !== rewriteUrl.pathname // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createNextMiddleware.mjs","names":[],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { applyTrailingSlash } from './pathname';\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport {\n normalizePathname,\n getSharedPath,\n replaceDynamicSegments,\n getLocalizedPath,\n getLocaleFromRequest,\n getResponse,\n ResponseConfig,\n} from './utils';\nimport { pathnameMatchesRegex } from '../utils/pathRegex';\nimport { createMiddlewareRouting } from './createMiddlewareRouting';\nimport { resolveMiddlewareConfig } from './resolveMiddlewareConfig';\nimport type { MiddlewareConfig } from './types';\nimport { createLinkRoutingConfigMismatchWarning } from '../errors/middleware';\n\nexport type { RouteOverrides, LocaleRoutes } from './types';\n\nconst NEXT_JS_SOURCE_MAP_PATH = '/__nextjs_source-map';\n\n// Options gt-next/link reads from withGTConfig() to avoid redirects.\nconst LINK_ROUTING_OPTIONS = [\n 'prefixDefaultLocale',\n 'enableSmartRouting',\n] as const;\n\n/**\n * Middleware factory to create a Next.js middleware for i18n routing and locale detection.\n *\n * This middleware sets a cookie based on the locale derived from several sources\n * such as the request pathname, referer, or 'Accept-Language' header.\n * If locale routing is enabled, it redirects to the localized pathname and\n * updates the locale cookie.\n *\n * Options omitted here fall back to the same options passed to `withGTConfig()`.\n *\n * @param {boolean} [config.localeRouting=true] - Flag to enable or disable automatic locale-based routing.\n * @param {boolean} [config.prefixDefaultLocale=false] - Flag to enable or disable prefixing the default locale to the pathname, i.e., /en/about -> /about\n * @param {boolean} [config.enableSmartRouting=true] - Keep automatic locale negotiation. Disable to treat returning visitors' unprefixed URLs as default-locale routes.\n * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps\n * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing\n * @param {RouteOverrides} [config.routeOverrides] - Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}\n * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale\n * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware(options: MiddlewareConfig = {}) {\n const config = resolveMiddlewareConfig(options);\n if (process.env.NODE_ENV === 'development') {\n const linkConfig = resolveMiddlewareConfig();\n const mismatches = LINK_ROUTING_OPTIONS.filter(\n (option) => config[option] !== linkConfig[option]\n );\n if (mismatches.length)\n console.warn(createLinkRoutingConfigMismatchWarning(mismatches));\n }\n const {\n localeRouting,\n prefixDefaultLocale,\n enableSmartRouting,\n ignoreSourceMaps,\n } = config;\n const {\n pathRegex,\n gt,\n defaultLocale,\n locales,\n localeRoutingEnabledCookieName,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n pathConfig,\n pathToSharedPath,\n defaultLocalePaths,\n routeOverridePathMaps,\n localeRoutePathMaps,\n } = createMiddlewareRouting(config);\n\n /**\n * Processes the incoming request to determine the user's locale and sets a locale cookie.\n * Optionally redirects the user based on the locale if locale-based routing is enabled.\n *\n * - Checks if the request URL contains a locale.\n * - Falls back to the referer URL for locale if needed.\n * - If no locale is found in the URL or referer, it checks the 'Accept-Language' header.\n * - Sets a cookie with the detected or default locale.\n * - Redirects to the correct locale route if locale routing is enabled.\n *\n * @param {NextRequest} req - The incoming request object, containing URL and headers.\n * @returns {NextResponse} - The Next.js response, either continuing the request or redirecting to the localized URL.\n */\n function middleware(req: NextRequest) {\n if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) {\n return NextResponse.next();\n }\n\n // Ignore source maps\n if (\n ignoreSourceMaps &&\n req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)\n ) {\n return NextResponse.next();\n }\n\n // ---------- LOCALE DETECTION ---------- //\n\n const {\n userLocale: requestedLocale,\n pathnameLocale: pathnameRoutingLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt,\n enableSmartRouting\n );\n\n let userLocale = requestedLocale;\n const pathnameLocale = pathnameRoutingLocale;\n const headerList = new Headers(req.headers);\n\n const responseConfig: Omit<ResponseConfig, 'type'> = {\n originalUrl: req.nextUrl,\n headerList,\n userLocale,\n clearResetCookie,\n localeRouting,\n localeRoutingEnabledCookieName,\n resetLocaleCookieName,\n localeHeaderName,\n };\n\n const getRewriteResponse = (responsePath: string) =>\n getResponse({ responsePath, type: 'rewrite', ...responseConfig });\n\n const getRedirectResponse = (responsePath: string) => {\n const response = getResponse({\n responsePath,\n type: 'redirect',\n ...responseConfig,\n });\n if (\n !enableSmartRouting &&\n !prefixDefaultLocale &&\n pathnameLocale === defaultLocale &&\n userLocale === defaultLocale &&\n req.headers.get('sec-fetch-dest') === 'document' &&\n !req.cookies.has(localeCookieName)\n ) {\n // Preserve explicit /en intent across a first document redirect.\n // Background fetches and returning visits must not change the cookie.\n response.cookies.set(localeCookieName, defaultLocale);\n }\n return response;\n };\n\n const getNextResponse = () =>\n getResponse({ type: 'next', ...responseConfig });\n\n if (localeRouting) {\n // ---------- GET PATHS ---------- //\n\n // get pathname\n const { pathname } = req.nextUrl;\n\n // standardize pathname (ie, /tg/welcome -> /fil/welcome), (/blog -> /blog)\n const standardizedPathname =\n pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale\n ? pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${pathnameLocale}`\n )\n : pathname;\n\n // Get the shared path for the unprefixed pathname\n const sharedPathMatch = getSharedPath(\n standardizedPathname,\n pathToSharedPath,\n pathnameLocale\n );\n const sharedPath = sharedPathMatch?.sharedPath;\n\n // Return early for a locale route that does not exist\n const localeRoutePathMap = localeRoutePathMaps.get(userLocale);\n if (userLocale !== defaultLocale && localeRoutePathMap) {\n // Resolve the shared page path without a locale prefix (e.g. /blog/hello).\n // Strip the URL's locale, which may differ from the newly selected locale.\n const sharedPagePath = sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n sharedPath || '/',\n sharedPathMatch.pathTemplate\n )\n : (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname) || '/';\n\n // If the path does not exist, redirect to the default locale path\n if (\n getSharedPath(sharedPagePath, localeRoutePathMap, undefined) ===\n undefined\n ) {\n // Get the path to redirect to\n const defaultPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, defaultLocale, pathConfig)\n : undefined;\n const fallbackPath =\n defaultPath !== undefined && sharedPathMatch\n ? replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n defaultPath,\n sharedPathMatch.pathTemplate\n )\n : `/${defaultLocale}${sharedPagePath === '/' ? '' : sharedPagePath}`;\n const publicFallbackPath = applyTrailingSlash(\n standardizedPathname,\n prefixDefaultLocale\n ? fallbackPath\n : fallbackPath.slice(defaultLocale.length + 1) || '/'\n );\n\n // The default locale is terminal, even if the preference/reset cookie\n // still requests an unavailable locale on the redirected request.\n userLocale = defaultLocale;\n responseConfig.userLocale = defaultLocale;\n const fallbackUrl = new URL(req.nextUrl);\n fallbackUrl.pathname = publicFallbackPath;\n if (fallbackUrl.pathname !== pathname) {\n return getRedirectResponse(publicFallbackPath);\n }\n // Already at the fallback URL: use normal default-locale routing below,\n // including its alias/override rewrite, instead of redirecting to itself.\n }\n }\n\n // Get shared path with parameters (/en/dashboard/1/custom), for rewriting localized paths\n const sharedPathWithParameters =\n sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n `/${userLocale}${sharedPath}`,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n // Localized path (/en/blog, /fr/fr-about, /fr/dashboard/[id]/custom)\n const localizedPath =\n sharedPath !== undefined\n ? getLocalizedPath(sharedPath, userLocale, pathConfig)\n : undefined;\n\n // Combine localized path with dynamic parameters (/en/blog, /fr/fr-about, /fr/dashboard/1/fr-custom)\n const localizedPathWithParameters =\n localizedPath !== undefined && sharedPathMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n replaceDynamicSegments(\n sharedPathMatch.matchedPathname,\n localizedPath,\n sharedPathMatch.pathTemplate\n )\n )\n : undefined;\n\n const pagePath =\n (sharedPathWithParameters?.slice(userLocale.length + 1) ??\n (pathnameLocale\n ? standardizedPathname.slice(pathnameLocale.length + 1)\n : standardizedPathname)) ||\n '/';\n const routeOverridePathMap = routeOverridePathMaps[userLocale];\n const routeOverrideMatch = routeOverridePathMap\n ? getSharedPath(pagePath, routeOverridePathMap, undefined)\n : undefined;\n const routeOverridePath =\n routeOverrideMatch !== undefined\n ? applyTrailingSlash(\n standardizedPathname,\n `/${userLocale}/${userLocale}${pagePath === '/' ? '' : pagePath}`\n )\n : undefined;\n\n // ---------- ROUTING LOGIC ---------- //\n\n // ----- CASE: no localized path exists ----- //\n\n if (localizedPathWithParameters === undefined) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/customers -> /customers)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n pathname.slice(\n (unstandardizedPathnameLocale as string).length + 1\n ) || '/'\n );\n }\n } else {\n // REWRITE CASE: no pathnameLocale (/customers -> /en/customers)\n return getRewriteResponse(\n routeOverridePath || `/${userLocale}${pathname}`\n );\n }\n }\n\n // --- CASE: defaultLocale prefix --- //\n // REDIRECT CASE: no pathnameLocale (ie, /customers -> /fr/customers)\n else if (!pathnameLocale) {\n return getRedirectResponse(`/${userLocale}${pathname}`);\n }\n\n // REDIRECT CASE: wrong pathnameLocale (ie, /fr/customers -> /en/customers) (this usually happens after a locale switch)\n if (pathnameLocale && userLocale !== unstandardizedPathnameLocale) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n `/${userLocale}`\n )\n );\n }\n\n // BASE CASE: has pathnameLocale and it's correct\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n return getNextResponse();\n }\n\n // ----- CASE: localized path exists ----- //\n\n if (!prefixDefaultLocale && userLocale === defaultLocale) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: explicit default locale or setLocale (/en/blog -> /blog)\n if (clearResetCookie || !enableSmartRouting) {\n return getRedirectResponse(\n localizedPathWithParameters.slice(userLocale.length + 1) || '/'\n );\n }\n } else {\n const localizedPublicPath =\n localizedPathWithParameters.slice(userLocale.length + 1) || '/';\n\n // REDIRECT CASE: unprefixed pathname is wrong (/about -> /en-about)\n if (\n !pathnameLocale &&\n normalizePathname(localizedPublicPath) !==\n normalizePathname(pathname)\n ) {\n return getRedirectResponse(localizedPublicPath);\n }\n\n // REWRITE CASE: displaying correct path (/blog -> /en/blog)\n return getRewriteResponse(\n routeOverridePath || (sharedPathWithParameters as string)\n );\n }\n }\n\n // --- CASE: add defaultLocale prefix --- //\n\n // REDIRECT CASE: incorrect pathnameLocale\n if (\n normalizePathname(pathname) !==\n normalizePathname(localizedPathWithParameters)\n ) {\n return getRedirectResponse(localizedPathWithParameters);\n }\n\n if (routeOverridePath) {\n return getRewriteResponse(routeOverridePath);\n }\n\n // REWRITE CASE: displaying correct localized path, which is the same as the shared path (/fil/blog => /fil/blog) (/fr/fr-dashboard/1/fr-custom => /fr/dashboard/1/custom)\n // Next.js route identity preserves Unicode spelling, even when lookup\n // considers the public alias and shared path canonically equivalent.\n const rewriteUrl = new URL(\n sharedPathWithParameters as string,\n req.nextUrl\n );\n if (\n req.nextUrl.pathname !== rewriteUrl.pathname // no rewrite needed if it's already the shared path\n ) {\n // convert to shared path with dynamic parameters\n return getRewriteResponse(sharedPathWithParameters as string);\n }\n }\n\n // BASE CASE\n return getNextResponse();\n }\n\n return middleware;\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { MiddlewareConfig, ResolvedMiddlewareConfig } from './types';
2
+ export declare const defaultMiddlewareConfig: Readonly<ResolvedMiddlewareConfig>;
3
+ /**
4
+ * Splits the middleware options that are set out of a config object.
5
+ * Unset (`undefined`) middleware options are dropped.
6
+ */
7
+ export declare function splitMiddlewareConfig<T extends MiddlewareConfig>(config: T): {
8
+ middlewareConfig: MiddlewareConfig;
9
+ otherConfig: Omit<T, keyof MiddlewareConfig>;
10
+ };
11
+ //# sourceMappingURL=defaultMiddlewareConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultMiddlewareConfig.d.ts","sourceRoot":"","sources":["../../src/middleware-dir/defaultMiddlewareConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAE1E,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,wBAAwB,CAQtE,CAAC;AAMF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,gBAAgB,EAC9D,MAAM,EAAE,CAAC,GACR;IACD,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,WAAW,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,gBAAgB,CAAC,CAAC;CAC9C,CAWA"}
@@ -0,0 +1,33 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/middleware-dir/defaultMiddlewareConfig.ts
3
+ const defaultMiddlewareConfig = {
4
+ localeRouting: true,
5
+ prefixDefaultLocale: false,
6
+ enableSmartRouting: true,
7
+ ignoreSourceMaps: true,
8
+ pathConfig: {},
9
+ routeOverrides: {},
10
+ localeRoutes: {}
11
+ };
12
+ const middlewareConfigKeys = Object.keys(defaultMiddlewareConfig);
13
+ /**
14
+ * Splits the middleware options that are set out of a config object.
15
+ * Unset (`undefined`) middleware options are dropped.
16
+ */
17
+ function splitMiddlewareConfig(config) {
18
+ const middlewareConfig = {};
19
+ const otherConfig = { ...config };
20
+ for (const key of middlewareConfigKeys) {
21
+ if (config[key] !== void 0) middlewareConfig[key] = config[key];
22
+ delete otherConfig[key];
23
+ }
24
+ return {
25
+ middlewareConfig,
26
+ otherConfig
27
+ };
28
+ }
29
+ //#endregion
30
+ exports.defaultMiddlewareConfig = defaultMiddlewareConfig;
31
+ exports.splitMiddlewareConfig = splitMiddlewareConfig;
32
+
33
+ //# sourceMappingURL=defaultMiddlewareConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultMiddlewareConfig.js","names":[],"sources":["../../src/middleware-dir/defaultMiddlewareConfig.ts"],"sourcesContent":["import type { MiddlewareConfig, ResolvedMiddlewareConfig } from './types';\n\nexport const defaultMiddlewareConfig: Readonly<ResolvedMiddlewareConfig> = {\n localeRouting: true,\n prefixDefaultLocale: false,\n enableSmartRouting: true,\n ignoreSourceMaps: true,\n pathConfig: {},\n routeOverrides: {},\n localeRoutes: {},\n};\n\nconst middlewareConfigKeys = Object.keys(\n defaultMiddlewareConfig\n) as (keyof MiddlewareConfig)[];\n\n/**\n * Splits the middleware options that are set out of a config object.\n * Unset (`undefined`) middleware options are dropped.\n */\nexport function splitMiddlewareConfig<T extends MiddlewareConfig>(\n config: T\n): {\n middlewareConfig: MiddlewareConfig;\n otherConfig: Omit<T, keyof MiddlewareConfig>;\n} {\n const middlewareConfig: Record<string, unknown> = {};\n const otherConfig: Record<string, unknown> = { ...config };\n for (const key of middlewareConfigKeys) {\n if (config[key] !== undefined) middlewareConfig[key] = config[key];\n delete otherConfig[key];\n }\n return {\n middlewareConfig: middlewareConfig as MiddlewareConfig,\n otherConfig: otherConfig as Omit<T, keyof MiddlewareConfig>,\n };\n}\n"],"mappings":";;AAEA,MAAa,0BAA8D;CACzE,eAAe;CACf,qBAAqB;CACrB,oBAAoB;CACpB,kBAAkB;CAClB,YAAY,EAAE;CACd,gBAAgB,EAAE;CAClB,cAAc,EAAE;CACjB;AAED,MAAM,uBAAuB,OAAO,KAClC,wBACD;;;;;AAMD,SAAgB,sBACd,QAIA;CACA,MAAM,mBAA4C,EAAE;CACpD,MAAM,cAAuC,EAAE,GAAG,QAAQ;AAC1D,MAAK,MAAM,OAAO,sBAAsB;AACtC,MAAI,OAAO,SAAS,KAAA,EAAW,kBAAiB,OAAO,OAAO;AAC9D,SAAO,YAAY;;AAErB,QAAO;EACa;EACL;EACd"}
@@ -0,0 +1,31 @@
1
+ //#region src/middleware-dir/defaultMiddlewareConfig.ts
2
+ const defaultMiddlewareConfig = {
3
+ localeRouting: true,
4
+ prefixDefaultLocale: false,
5
+ enableSmartRouting: true,
6
+ ignoreSourceMaps: true,
7
+ pathConfig: {},
8
+ routeOverrides: {},
9
+ localeRoutes: {}
10
+ };
11
+ const middlewareConfigKeys = Object.keys(defaultMiddlewareConfig);
12
+ /**
13
+ * Splits the middleware options that are set out of a config object.
14
+ * Unset (`undefined`) middleware options are dropped.
15
+ */
16
+ function splitMiddlewareConfig(config) {
17
+ const middlewareConfig = {};
18
+ const otherConfig = { ...config };
19
+ for (const key of middlewareConfigKeys) {
20
+ if (config[key] !== void 0) middlewareConfig[key] = config[key];
21
+ delete otherConfig[key];
22
+ }
23
+ return {
24
+ middlewareConfig,
25
+ otherConfig
26
+ };
27
+ }
28
+ //#endregion
29
+ export { defaultMiddlewareConfig, splitMiddlewareConfig };
30
+
31
+ //# sourceMappingURL=defaultMiddlewareConfig.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultMiddlewareConfig.mjs","names":[],"sources":["../../src/middleware-dir/defaultMiddlewareConfig.ts"],"sourcesContent":["import type { MiddlewareConfig, ResolvedMiddlewareConfig } from './types';\n\nexport const defaultMiddlewareConfig: Readonly<ResolvedMiddlewareConfig> = {\n localeRouting: true,\n prefixDefaultLocale: false,\n enableSmartRouting: true,\n ignoreSourceMaps: true,\n pathConfig: {},\n routeOverrides: {},\n localeRoutes: {},\n};\n\nconst middlewareConfigKeys = Object.keys(\n defaultMiddlewareConfig\n) as (keyof MiddlewareConfig)[];\n\n/**\n * Splits the middleware options that are set out of a config object.\n * Unset (`undefined`) middleware options are dropped.\n */\nexport function splitMiddlewareConfig<T extends MiddlewareConfig>(\n config: T\n): {\n middlewareConfig: MiddlewareConfig;\n otherConfig: Omit<T, keyof MiddlewareConfig>;\n} {\n const middlewareConfig: Record<string, unknown> = {};\n const otherConfig: Record<string, unknown> = { ...config };\n for (const key of middlewareConfigKeys) {\n if (config[key] !== undefined) middlewareConfig[key] = config[key];\n delete otherConfig[key];\n }\n return {\n middlewareConfig: middlewareConfig as MiddlewareConfig,\n otherConfig: otherConfig as Omit<T, keyof MiddlewareConfig>,\n };\n}\n"],"mappings":";AAEA,MAAa,0BAA8D;CACzE,eAAe;CACf,qBAAqB;CACrB,oBAAoB;CACpB,kBAAkB;CAClB,YAAY,EAAE;CACd,gBAAgB,EAAE;CAClB,cAAc,EAAE;CACjB;AAED,MAAM,uBAAuB,OAAO,KAClC,wBACD;;;;;AAMD,SAAgB,sBACd,QAIA;CACA,MAAM,mBAA4C,EAAE;CACpD,MAAM,cAAuC,EAAE,GAAG,QAAQ;AAC1D,MAAK,MAAM,OAAO,sBAAsB;AACtC,MAAI,OAAO,SAAS,KAAA,EAAW,kBAAiB,OAAO,OAAO;AAC9D,SAAO,YAAY;;AAErB,QAAO;EACa;EACL;EACd"}
@@ -0,0 +1,9 @@
1
+ import type { MiddlewareConfig, ResolvedMiddlewareConfig } from './types';
2
+ /** Parses a JSON env var written by `withGTConfig()`. */
3
+ export declare function parseEnvConfig<T extends object>(envName: string, value: string | undefined): Partial<T>;
4
+ /**
5
+ * Resolves middleware options with precedence:
6
+ * `createNextMiddleware()` options > `withGTConfig()` options > defaults.
7
+ */
8
+ export declare function resolveMiddlewareConfig(options?: MiddlewareConfig): ResolvedMiddlewareConfig;
9
+ //# sourceMappingURL=resolveMiddlewareConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveMiddlewareConfig.d.ts","sourceRoot":"","sources":["../../src/middleware-dir/resolveMiddlewareConfig.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAE1E,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,gBAAqB,GAC7B,wBAAwB,CAY1B"}
@@ -0,0 +1,32 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_middleware_dir_defaultMiddlewareConfig = require("./defaultMiddlewareConfig.js");
3
+ const require_errors_middleware = require("../errors/middleware.js");
4
+ //#region src/middleware-dir/resolveMiddlewareConfig.ts
5
+ /** Parses a JSON env var written by `withGTConfig()`. */
6
+ function parseEnvConfig(envName, value) {
7
+ if (!value) return {};
8
+ try {
9
+ const parsed = JSON.parse(value);
10
+ return parsed && typeof parsed === "object" ? parsed : {};
11
+ } catch (error) {
12
+ console.error(require_errors_middleware.createInvalidMiddlewareEnvConfigError(envName, error));
13
+ return {};
14
+ }
15
+ }
16
+ /**
17
+ * Resolves middleware options with precedence:
18
+ * `createNextMiddleware()` options > `withGTConfig()` options > defaults.
19
+ */
20
+ function resolveMiddlewareConfig(options = {}) {
21
+ const envConfig = parseEnvConfig("_GENERALTRANSLATION_MIDDLEWARE_CONFIG", process.env._GENERALTRANSLATION_MIDDLEWARE_CONFIG);
22
+ return {
23
+ ...require_middleware_dir_defaultMiddlewareConfig.defaultMiddlewareConfig,
24
+ ...require_middleware_dir_defaultMiddlewareConfig.splitMiddlewareConfig(envConfig).middlewareConfig,
25
+ ...require_middleware_dir_defaultMiddlewareConfig.splitMiddlewareConfig(options).middlewareConfig
26
+ };
27
+ }
28
+ //#endregion
29
+ exports.parseEnvConfig = parseEnvConfig;
30
+ exports.resolveMiddlewareConfig = resolveMiddlewareConfig;
31
+
32
+ //# sourceMappingURL=resolveMiddlewareConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveMiddlewareConfig.js","names":["createInvalidMiddlewareEnvConfigError","defaultMiddlewareConfig","splitMiddlewareConfig"],"sources":["../../src/middleware-dir/resolveMiddlewareConfig.ts"],"sourcesContent":["import { createInvalidMiddlewareEnvConfigError } from '../errors/middleware';\nimport {\n defaultMiddlewareConfig,\n splitMiddlewareConfig,\n} from './defaultMiddlewareConfig';\nimport type { MiddlewareConfig, ResolvedMiddlewareConfig } from './types';\n\n/** Parses a JSON env var written by `withGTConfig()`. */\nexport function parseEnvConfig<T extends object>(\n envName: string,\n value: string | undefined\n): Partial<T> {\n if (!value) return {};\n try {\n const parsed: unknown = JSON.parse(value);\n // Valid JSON that isn't an object (e.g. `null`) is treated as unset.\n return parsed && typeof parsed === 'object' ? (parsed as Partial<T>) : {};\n } catch (error) {\n console.error(createInvalidMiddlewareEnvConfigError(envName, error));\n return {};\n }\n}\n\n/**\n * Resolves middleware options with precedence:\n * `createNextMiddleware()` options > `withGTConfig()` options > defaults.\n */\nexport function resolveMiddlewareConfig(\n options: MiddlewareConfig = {}\n): ResolvedMiddlewareConfig {\n // Read each env var through a literal `process.env` access so Next.js can\n // inline the values from `nextConfig.env`.\n const envConfig = parseEnvConfig<MiddlewareConfig>(\n '_GENERALTRANSLATION_MIDDLEWARE_CONFIG',\n process.env._GENERALTRANSLATION_MIDDLEWARE_CONFIG\n );\n return {\n ...defaultMiddlewareConfig,\n ...splitMiddlewareConfig(envConfig).middlewareConfig,\n ...splitMiddlewareConfig(options).middlewareConfig,\n };\n}\n"],"mappings":";;;;;AAQA,SAAgB,eACd,SACA,OACY;AACZ,KAAI,CAAC,MAAO,QAAO,EAAE;AACrB,KAAI;EACF,MAAM,SAAkB,KAAK,MAAM,MAAM;AAEzC,SAAO,UAAU,OAAO,WAAW,WAAY,SAAwB,EAAE;UAClE,OAAO;AACd,UAAQ,MAAMA,0BAAAA,sCAAsC,SAAS,MAAM,CAAC;AACpE,SAAO,EAAE;;;;;;;AAQb,SAAgB,wBACd,UAA4B,EAAE,EACJ;CAG1B,MAAM,YAAY,eAChB,yCACA,QAAQ,IAAI,sCACb;AACD,QAAO;EACL,GAAGC,+CAAAA;EACH,GAAGC,+CAAAA,sBAAsB,UAAU,CAAC;EACpC,GAAGA,+CAAAA,sBAAsB,QAAQ,CAAC;EACnC"}
@@ -0,0 +1,30 @@
1
+ import { defaultMiddlewareConfig, splitMiddlewareConfig } from "./defaultMiddlewareConfig.mjs";
2
+ import { createInvalidMiddlewareEnvConfigError } from "../errors/middleware.mjs";
3
+ //#region src/middleware-dir/resolveMiddlewareConfig.ts
4
+ /** Parses a JSON env var written by `withGTConfig()`. */
5
+ function parseEnvConfig(envName, value) {
6
+ if (!value) return {};
7
+ try {
8
+ const parsed = JSON.parse(value);
9
+ return parsed && typeof parsed === "object" ? parsed : {};
10
+ } catch (error) {
11
+ console.error(createInvalidMiddlewareEnvConfigError(envName, error));
12
+ return {};
13
+ }
14
+ }
15
+ /**
16
+ * Resolves middleware options with precedence:
17
+ * `createNextMiddleware()` options > `withGTConfig()` options > defaults.
18
+ */
19
+ function resolveMiddlewareConfig(options = {}) {
20
+ const envConfig = parseEnvConfig("_GENERALTRANSLATION_MIDDLEWARE_CONFIG", process.env._GENERALTRANSLATION_MIDDLEWARE_CONFIG);
21
+ return {
22
+ ...defaultMiddlewareConfig,
23
+ ...splitMiddlewareConfig(envConfig).middlewareConfig,
24
+ ...splitMiddlewareConfig(options).middlewareConfig
25
+ };
26
+ }
27
+ //#endregion
28
+ export { parseEnvConfig, resolveMiddlewareConfig };
29
+
30
+ //# sourceMappingURL=resolveMiddlewareConfig.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveMiddlewareConfig.mjs","names":[],"sources":["../../src/middleware-dir/resolveMiddlewareConfig.ts"],"sourcesContent":["import { createInvalidMiddlewareEnvConfigError } from '../errors/middleware';\nimport {\n defaultMiddlewareConfig,\n splitMiddlewareConfig,\n} from './defaultMiddlewareConfig';\nimport type { MiddlewareConfig, ResolvedMiddlewareConfig } from './types';\n\n/** Parses a JSON env var written by `withGTConfig()`. */\nexport function parseEnvConfig<T extends object>(\n envName: string,\n value: string | undefined\n): Partial<T> {\n if (!value) return {};\n try {\n const parsed: unknown = JSON.parse(value);\n // Valid JSON that isn't an object (e.g. `null`) is treated as unset.\n return parsed && typeof parsed === 'object' ? (parsed as Partial<T>) : {};\n } catch (error) {\n console.error(createInvalidMiddlewareEnvConfigError(envName, error));\n return {};\n }\n}\n\n/**\n * Resolves middleware options with precedence:\n * `createNextMiddleware()` options > `withGTConfig()` options > defaults.\n */\nexport function resolveMiddlewareConfig(\n options: MiddlewareConfig = {}\n): ResolvedMiddlewareConfig {\n // Read each env var through a literal `process.env` access so Next.js can\n // inline the values from `nextConfig.env`.\n const envConfig = parseEnvConfig<MiddlewareConfig>(\n '_GENERALTRANSLATION_MIDDLEWARE_CONFIG',\n process.env._GENERALTRANSLATION_MIDDLEWARE_CONFIG\n );\n return {\n ...defaultMiddlewareConfig,\n ...splitMiddlewareConfig(envConfig).middlewareConfig,\n ...splitMiddlewareConfig(options).middlewareConfig,\n };\n}\n"],"mappings":";;;;AAQA,SAAgB,eACd,SACA,OACY;AACZ,KAAI,CAAC,MAAO,QAAO,EAAE;AACrB,KAAI;EACF,MAAM,SAAkB,KAAK,MAAM,MAAM;AAEzC,SAAO,UAAU,OAAO,WAAW,WAAY,SAAwB,EAAE;UAClE,OAAO;AACd,UAAQ,MAAM,sCAAsC,SAAS,MAAM,CAAC;AACpE,SAAO,EAAE;;;;;;;AAQb,SAAgB,wBACd,UAA4B,EAAE,EACJ;CAG1B,MAAM,YAAY,eAChB,yCACA,QAAQ,IAAI,sCACb;AACD,QAAO;EACL,GAAG;EACH,GAAG,sBAAsB,UAAU,CAAC;EACpC,GAAG,sBAAsB,QAAQ,CAAC;EACnC"}
@@ -0,0 +1,56 @@
1
+ import type { GTRuntime } from 'generaltranslation/runtime';
2
+ import type { CustomMapping } from '@generaltranslation/format/types';
3
+ import type { HeadersAndCookies } from '../config-dir/props/withGTConfigProps';
4
+ import type { PathConfig, PathMatcher } from './createPathMatcher';
5
+ export type RouteOverrides = Record<string, readonly string[]>;
6
+ export type LocaleRoutes = Record<string, readonly string[]>;
7
+ /**
8
+ * Locale routing options accepted by both `createNextMiddleware()` and
9
+ * `withGTConfig()`. Options passed to `createNextMiddleware()` take precedence.
10
+ */
11
+ export type MiddlewareConfig = {
12
+ /** Enable automatic locale-based routing. */
13
+ localeRouting?: boolean;
14
+ /** Prefix the default locale to the pathname, i.e. `/about` -> `/en/about`. */
15
+ prefixDefaultLocale?: boolean;
16
+ /**
17
+ * Keep automatic locale negotiation. Disable to treat returning visitors'
18
+ * unprefixed URLs as default-locale routes.
19
+ */
20
+ enableSmartRouting?: boolean;
21
+ /** Skip Next.js source map requests. */
22
+ ignoreSourceMaps?: boolean;
23
+ /** Localized path aliases. */
24
+ pathConfig?: PathConfig;
25
+ /** Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}. */
26
+ routeOverrides?: RouteOverrides;
27
+ /** Shared paths available per locale; other paths fall back to the default locale. */
28
+ localeRoutes?: LocaleRoutes;
29
+ };
30
+ export type ResolvedMiddlewareConfig = Required<MiddlewareConfig>;
31
+ /** The subset of the i18n config params read by the middleware. */
32
+ export type MiddlewareI18nConfig = {
33
+ customMapping?: CustomMapping;
34
+ defaultLocale?: string;
35
+ locales?: string[];
36
+ headersAndCookies?: HeadersAndCookies;
37
+ };
38
+ /** Locale, cookie, and path state pre-processed once per middleware instance. */
39
+ export type MiddlewareRouting = {
40
+ pathRegex: RegExp | undefined;
41
+ gt: GTRuntime;
42
+ defaultLocale: string;
43
+ locales: string[];
44
+ localeRoutingEnabledCookieName: string;
45
+ referrerLocaleCookieName: string;
46
+ localeCookieName: string;
47
+ resetLocaleCookieName: string;
48
+ localeHeaderName: string;
49
+ /** `pathConfig` with locale keys resolved to their configured spelling. */
50
+ pathConfig: PathConfig;
51
+ pathToSharedPath: PathMatcher;
52
+ defaultLocalePaths: PathMatcher;
53
+ routeOverridePathMaps: Record<string, PathMatcher>;
54
+ localeRoutePathMaps: Map<string, PathMatcher>;
55
+ };
56
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/middleware-dir/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAE7D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8BAA8B;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,2FAA2F;IAC3F,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,sFAAsF;IACtF,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAElE,mEAAmE;AACnE,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC,CAAC;AAEF,iFAAiF;AACjF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,EAAE,EAAE,SAAS,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8BAA8B,EAAE,MAAM,CAAC;IACvC,wBAAwB,EAAE,MAAM,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,UAAU,EAAE,UAAU,CAAC;IACvB,gBAAgB,EAAE,WAAW,CAAC;IAC9B,kBAAkB,EAAE,WAAW,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnD,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC/C,CAAC"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
@@ -0,0 +1 @@
1
+ export {};
package/dist/server.d.ts CHANGED
@@ -6,6 +6,7 @@ export { getLocale } from './request/getLocale';
6
6
  export { getLocaleDirection } from './request/getLocaleDirection';
7
7
  export { registerLocale } from './request/registerLocale';
8
8
  export { resolveCanonicalLocale } from 'gt-i18n';
9
+ export { getLocalizeHref } from './link/getLocalizeHref';
9
10
  export { getRegion } from './request/getRegion';
10
11
  export { tx } from './server-dir/runtime/tx';
11
12
  export { Tx } from './server-dir/runtime/_Tx';
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAKrB;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAC;AAC7C,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,WAAW,EACX,KAAK,GACN,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAKrB;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAC;AAC7C,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,WAAW,EACX,KAAK,GACN,MAAM,gCAAgC,CAAC"}