gt-next 11.2.1 → 11.3.0

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 (54) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +2 -7
  4. package/dist/config.js.map +1 -1
  5. package/dist/config.mjs +4 -9
  6. package/dist/config.mjs.map +1 -1
  7. package/dist/errors/createErrors.d.ts +0 -1
  8. package/dist/errors/createErrors.d.ts.map +1 -1
  9. package/dist/errors/createErrors.js +0 -2
  10. package/dist/errors/createErrors.js.map +1 -1
  11. package/dist/errors/createErrors.mjs +1 -2
  12. package/dist/errors/createErrors.mjs.map +1 -1
  13. package/dist/middleware-dir/createNextMiddleware.d.ts +4 -1
  14. package/dist/middleware-dir/createNextMiddleware.d.ts.map +1 -1
  15. package/dist/middleware-dir/createNextMiddleware.js +38 -13
  16. package/dist/middleware-dir/createNextMiddleware.js.map +1 -1
  17. package/dist/middleware-dir/createNextMiddleware.mjs +39 -14
  18. package/dist/middleware-dir/createNextMiddleware.mjs.map +1 -1
  19. package/dist/middleware-dir/utils.d.ts +1 -1
  20. package/dist/middleware-dir/utils.d.ts.map +1 -1
  21. package/dist/middleware-dir/utils.js +5 -11
  22. package/dist/middleware-dir/utils.js.map +1 -1
  23. package/dist/middleware-dir/utils.mjs +5 -11
  24. package/dist/middleware-dir/utils.mjs.map +1 -1
  25. package/dist/middleware.d.ts +1 -1
  26. package/dist/middleware.d.ts.map +1 -1
  27. package/dist/plugin/constants.d.ts +1 -0
  28. package/dist/plugin/constants.d.ts.map +1 -1
  29. package/dist/plugin/constants.js +2 -0
  30. package/dist/plugin/constants.js.map +1 -1
  31. package/dist/plugin/constants.mjs +2 -1
  32. package/dist/plugin/constants.mjs.map +1 -1
  33. package/dist/plugin/getStableNextVersionInfo.d.ts +1 -0
  34. package/dist/plugin/getStableNextVersionInfo.d.ts.map +1 -1
  35. package/dist/plugin/getStableNextVersionInfo.js +2 -0
  36. package/dist/plugin/getStableNextVersionInfo.js.map +1 -1
  37. package/dist/plugin/getStableNextVersionInfo.mjs +3 -2
  38. package/dist/plugin/getStableNextVersionInfo.mjs.map +1 -1
  39. package/dist/provider/GTProvider.d.ts.map +1 -1
  40. package/dist/provider/GTProvider.js +10 -5
  41. package/dist/provider/GTProvider.js.map +1 -1
  42. package/dist/provider/GTProvider.mjs +10 -5
  43. package/dist/provider/GTProvider.mjs.map +1 -1
  44. package/dist/request/localeValidation.js +2 -2
  45. package/dist/request/localeValidation.js.map +1 -1
  46. package/dist/request/localeValidation.mjs +2 -2
  47. package/dist/request/localeValidation.mjs.map +1 -1
  48. package/dist/utils/client-boundary.d.ts +4 -1
  49. package/dist/utils/client-boundary.d.ts.map +1 -1
  50. package/dist/utils/client-boundary.js +14 -10
  51. package/dist/utils/client-boundary.js.map +1 -1
  52. package/dist/utils/client-boundary.mjs +14 -10
  53. package/dist/utils/client-boundary.mjs.map +1 -1
  54. package/package.json +8 -8
@@ -92,7 +92,6 @@ const APIKeyMissingWarn = require_errors_diagnostics.createGtNextPluginDiagnosti
92
92
  whatHappened: "Runtime translation needs a development API key",
93
93
  fix: "Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation"
94
94
  });
95
- const standardizedLocalesWarning = (locales) => `gt-next: The following locales were standardized: ${locales.join(", ")}. Use the standardized codes in your config to avoid this warning.`;
96
95
  const standardizedCanonicalLocalesWarning = (locales) => `gt-next: The following canonical locales were standardized: ${locales.join(", ")}. Use the standardized codes in your config to avoid this warning.`;
97
96
  const createNextI18nConfigMismatchWarning = (details) => require_errors_diagnostics.createGtNextPluginDiagnostic({
98
97
  severity: "Warning",
@@ -150,7 +149,6 @@ exports.invalidLocalesError = invalidLocalesError;
150
149
  exports.projectIdMissingWarn = projectIdMissingWarn;
151
150
  exports.remoteTranslationsError = remoteTranslationsError;
152
151
  exports.standardizedCanonicalLocalesWarning = standardizedCanonicalLocalesWarning;
153
- exports.standardizedLocalesWarning = standardizedLocalesWarning;
154
152
  exports.swcPluginCompatibilityChangeWarning = swcPluginCompatibilityChangeWarning;
155
153
  exports.typesFileError = typesFileError;
156
154
  exports.unresolvedLoadDictionaryBuildError = unresolvedLoadDictionaryBuildError;
@@ -1 +1 @@
1
- {"version":3,"file":"createErrors.js","names":["createGtNextDiagnostic","createGtNextPluginDiagnostic","SWC_PLUGIN_SUPPORT","BABEL_PLUGIN_SUPPORT"],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const withGTStaticPropsRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'withGTStaticProps() is not available for React Server Components',\n why: 'this helper supports the Pages Router, not the App Router',\n fix: 'Use gt-next build-time translation helpers in the App Router, or export withGTStaticProps() from a Pages Router page module',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createNextI18nConfigMismatchWarning = (details: string[]) =>\n createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened:\n 'Next.js internationalized routing does not match the GT config file',\n why: 'Next.js may select a locale that GT is not configured to translate',\n fix: 'Use the same defaultLocale and locales values in both configurations',\n details,\n });\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n createGtNextPluginDiagnostic({\n whatHappened: `The GT ${type} compiler could not be resolved`,\n wayOut: 'Skipping compiler optimizations',\n ...(type === 'babel' && {\n fix: 'Install @generaltranslation/compiler to enable the experimental babel compiler',\n }),\n });\n\nexport const autoJsxInjectionCompilerWarning = createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened: 'Automatic JSX injection requires the GT webpack compiler',\n wayOut: 'Automatic JSX injection will be skipped',\n fix: \"Set experimentalCompilerOptions.type to 'babel' in withGTConfig() and build with webpack\",\n});\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"createErrors.js","names":["createGtNextDiagnostic","createGtNextPluginDiagnostic","SWC_PLUGIN_SUPPORT","BABEL_PLUGIN_SUPPORT"],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const withGTStaticPropsRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'withGTStaticProps() is not available for React Server Components',\n why: 'this helper supports the Pages Router, not the App Router',\n fix: 'Use gt-next build-time translation helpers in the App Router, or export withGTStaticProps() from a Pages Router page module',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createNextI18nConfigMismatchWarning = (details: string[]) =>\n createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened:\n 'Next.js internationalized routing does not match the GT config file',\n why: 'Next.js may select a locale that GT is not configured to translate',\n fix: 'Use the same defaultLocale and locales values in both configurations',\n details,\n });\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n createGtNextPluginDiagnostic({\n whatHappened: `The GT ${type} compiler could not be resolved`,\n wayOut: 'Skipping compiler optimizations',\n ...(type === 'babel' && {\n fix: 'Install @generaltranslation/compiler to enable the experimental babel compiler',\n }),\n });\n\nexport const autoJsxInjectionCompilerWarning = createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened: 'Automatic JSX injection requires the GT webpack compiler',\n wayOut: 'Automatic JSX injection will be skipped',\n fix: \"Set experimentalCompilerOptions.type to 'babel' in withGTConfig() and build with webpack\",\n});\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":"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"}
@@ -91,7 +91,6 @@ const APIKeyMissingWarn = createGtNextPluginDiagnostic({
91
91
  whatHappened: "Runtime translation needs a development API key",
92
92
  fix: "Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation"
93
93
  });
94
- const standardizedLocalesWarning = (locales) => `gt-next: The following locales were standardized: ${locales.join(", ")}. Use the standardized codes in your config to avoid this warning.`;
95
94
  const standardizedCanonicalLocalesWarning = (locales) => `gt-next: The following canonical locales were standardized: ${locales.join(", ")}. Use the standardized codes in your config to avoid this warning.`;
96
95
  const createNextI18nConfigMismatchWarning = (details) => createGtNextPluginDiagnostic({
97
96
  severity: "Warning",
@@ -126,6 +125,6 @@ const babelCompilerTurbopackUnavailableWarning = "gt-next (plugin): The GT babel
126
125
  const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;
127
126
  const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;
128
127
  //#endregion
129
- export { APIKeyMissingWarn, autoJsxInjectionCompilerWarning, babelCompilerTurbopackUnavailableWarning, conflictingConfigurationBuildError, createBadFilepathWarning, createDictionarySubsetError, createGTCompilerUnavailableWarning, createGTCompilerUnresolvedWarning, createNextI18nConfigMismatchWarning, createUnresolvedNextVersionError, createUnresolvedReactVersionError, customGetLocaleUnresolvedWarning, customGetRegionUnresolvedWarning, customLoadDictionaryWarning, customLoadTranslationsError, devApiKeyIncludedInProductionError, disablingCompileTimeHashWarning, getTranslationsSnapshotRscError, invalidCanonicalLocalesError, invalidLocalesError, projectIdMissingWarn, remoteTranslationsError, standardizedCanonicalLocalesWarning, standardizedLocalesWarning, swcPluginCompatibilityChangeWarning, typesFileError, unresolvedLoadDictionaryBuildError, unresolvedLoadTranslationsBuildError, withGTStaticPropsRscError };
128
+ export { APIKeyMissingWarn, autoJsxInjectionCompilerWarning, babelCompilerTurbopackUnavailableWarning, conflictingConfigurationBuildError, createBadFilepathWarning, createDictionarySubsetError, createGTCompilerUnavailableWarning, createGTCompilerUnresolvedWarning, createNextI18nConfigMismatchWarning, createUnresolvedNextVersionError, createUnresolvedReactVersionError, customGetLocaleUnresolvedWarning, customGetRegionUnresolvedWarning, customLoadDictionaryWarning, customLoadTranslationsError, devApiKeyIncludedInProductionError, disablingCompileTimeHashWarning, getTranslationsSnapshotRscError, invalidCanonicalLocalesError, invalidLocalesError, projectIdMissingWarn, remoteTranslationsError, standardizedCanonicalLocalesWarning, swcPluginCompatibilityChangeWarning, typesFileError, unresolvedLoadDictionaryBuildError, unresolvedLoadTranslationsBuildError, withGTStaticPropsRscError };
130
129
 
131
130
  //# sourceMappingURL=createErrors.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"createErrors.mjs","names":[],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const withGTStaticPropsRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'withGTStaticProps() is not available for React Server Components',\n why: 'this helper supports the Pages Router, not the App Router',\n fix: 'Use gt-next build-time translation helpers in the App Router, or export withGTStaticProps() from a Pages Router page module',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedLocalesWarning = (locales: string[]) =>\n `gt-next: The following locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createNextI18nConfigMismatchWarning = (details: string[]) =>\n createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened:\n 'Next.js internationalized routing does not match the GT config file',\n why: 'Next.js may select a locale that GT is not configured to translate',\n fix: 'Use the same defaultLocale and locales values in both configurations',\n details,\n });\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n createGtNextPluginDiagnostic({\n whatHappened: `The GT ${type} compiler could not be resolved`,\n wayOut: 'Skipping compiler optimizations',\n ...(type === 'babel' && {\n fix: 'Install @generaltranslation/compiler to enable the experimental babel compiler',\n }),\n });\n\nexport const autoJsxInjectionCompilerWarning = createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened: 'Automatic JSX injection requires the GT webpack compiler',\n wayOut: 'Automatic JSX injection will be skipped',\n fix: \"Set experimentalCompilerOptions.type to 'babel' in withGTConfig() and build with webpack\",\n});\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":"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"}
1
+ {"version":3,"file":"createErrors.mjs","names":[],"sources":["../../src/errors/createErrors.ts"],"sourcesContent":["// ---- ERRORS ---- //\n\nimport {\n createGtNextDiagnostic,\n createGtNextPluginDiagnostic,\n} from './diagnostics';\nimport { BABEL_PLUGIN_SUPPORT, SWC_PLUGIN_SUPPORT } from '../plugin/constants';\n\nexport const remoteTranslationsError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Remote translations could not be loaded',\n fix: 'Check your project ID, API key, and network connection, then try again',\n wayOut: 'Source content will render as a fallback',\n});\n\nexport const customLoadTranslationsError = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `Locally stored translations could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadTranslations(), make sure it returns translations for the requested locale',\n });\n\nexport const customLoadDictionaryWarning = (locale: string = '') =>\n createGtNextDiagnostic({\n severity: 'Warning',\n whatHappened: `The local dictionary could not be loaded${locale ? ` for \"${locale}\"` : ''}`,\n fix: 'If you use loadDictionary(), make sure it returns a dictionary for the requested locale',\n });\n\nexport const createUnresolvedNextVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed Next.js version could not be resolved',\n fix: 'Check that next is installed in this project',\n details: error.message,\n });\n\nexport const createUnresolvedReactVersionError = (error: Error) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'The installed React version could not be resolved',\n fix: 'Check that react is installed in this project',\n details: error.message,\n });\n\nexport const devApiKeyIncludedInProductionError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Production builds cannot use a development API key',\n fix: 'Replace it with a production API key',\n});\n\nexport const createDictionarySubsetError = (id: string, functionName: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `${functionName} with id \"${id}\" could not read a valid dictionary subtree`,\n fix: 'Make sure the id maps to the correct subroute of the dictionary',\n });\n\nexport const unresolvedLoadDictionaryBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadDictionary() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const unresolvedLoadTranslationsBuildError = (path: string) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: `The file defining loadTranslations() could not be resolved at ${path}`,\n fix: 'Check the configured path and try again',\n });\n\nexport const conflictingConfigurationBuildError = (conflicts: string[]) =>\n `gt-next Error: Conflicting configuration${\n conflicts.length > 1 ? 's' : ''\n } detected. Resolve the following conflicts before building your app:\\n${conflicts.join(\n '\\n'\n )}`;\n\nexport const typesFileError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'A types-only entry point was executed at runtime',\n fix: 'Import from the appropriate gt-next runtime entry point instead',\n});\n\nexport const getTranslationsSnapshotRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'getTranslationsSnapshot() is not available for React Server Components',\n fix: 'Use gt-next build-time translation helpers in the App Router, or call getTranslationsSnapshot() from a Pages Router entry point',\n});\n\nexport const withGTStaticPropsRscError = createGtNextDiagnostic({\n severity: 'Error',\n whatHappened:\n 'withGTStaticProps() is not available for React Server Components',\n why: 'this helper supports the Pages Router, not the App Router',\n fix: 'Use gt-next build-time translation helpers in the App Router, or export withGTStaticProps() from a Pages Router page module',\n});\n\nexport const invalidLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid locale codes in your configuration',\n fix: 'Specify a list of valid locales or use \"customMapping\" to define aliases for the invalid locales',\n details: locales,\n });\n\nexport const invalidCanonicalLocalesError = (locales: string[]) =>\n createGtNextDiagnostic({\n severity: 'Error',\n whatHappened: 'Invalid canonical locale codes in your configuration',\n fix: 'Use valid BCP 47 locale codes before starting translation',\n details: locales,\n });\n\n// ---- WARNINGS ---- //\n\nexport const createBadFilepathWarning = (filename: string, dir: string[]) =>\n createGtNextDiagnostic({\n whatHappened: `${filename} was found in ${dir.join(' or ')}, which is not supported`,\n fix: 'Move it to your project root so gt-next can load it',\n });\n\nexport const projectIdMissingWarn = createGtNextDiagnostic({\n whatHappened: 'Runtime translation needs a project ID',\n fix: 'Set GT_PROJECT_ID in your environment or pass projectId to withGTConfig()',\n docsUrl: 'https://generaltranslation.com/dashboard',\n});\n\nexport const APIKeyMissingWarn = createGtNextPluginDiagnostic({\n whatHappened: 'Runtime translation needs a development API key',\n fix: 'Find your development API key at generaltranslation.com/dashboard, or set runtimeUrl to an empty string to disable runtime translation',\n});\n\nexport const standardizedCanonicalLocalesWarning = (locales: string[]) =>\n `gt-next: The following canonical locales were standardized: ${locales.join(', ')}. Use the standardized codes in your config to avoid this warning.`;\n\nexport const createNextI18nConfigMismatchWarning = (details: string[]) =>\n createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened:\n 'Next.js internationalized routing does not match the GT config file',\n why: 'Next.js may select a locale that GT is not configured to translate',\n fix: 'Use the same defaultLocale and locales values in both configurations',\n details,\n });\n\nexport const createGTCompilerUnresolvedWarning = (type: 'babel' | 'swc') =>\n createGtNextPluginDiagnostic({\n whatHappened: `The GT ${type} compiler could not be resolved`,\n wayOut: 'Skipping compiler optimizations',\n ...(type === 'babel' && {\n fix: 'Install @generaltranslation/compiler to enable the experimental babel compiler',\n }),\n });\n\nexport const autoJsxInjectionCompilerWarning = createGtNextPluginDiagnostic({\n severity: 'Warning',\n whatHappened: 'Automatic JSX injection requires the GT webpack compiler',\n wayOut: 'Automatic JSX injection will be skipped',\n fix: \"Set experimentalCompilerOptions.type to 'babel' in withGTConfig() and build with webpack\",\n});\n\nexport const customGetLocaleUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getLocale() could not be resolved',\n wayOut: 'gt-next will fall back to default locale detection',\n fix: 'Export a getLocale() function from the configured request file',\n});\n\nexport const customGetRegionUnresolvedWarning = createGtNextDiagnostic({\n whatHappened: 'Custom getRegion() could not be resolved',\n wayOut: 'gt-next will fall back to default region detection',\n fix: 'Export a getRegion() function from the configured request file',\n});\n\nexport const createGTCompilerUnavailableWarning = (type: 'babel' | 'swc') =>\n type === 'swc'\n ? `gt-next (plugin): The GT swc compiler is compatible with < next@${SWC_PLUGIN_SUPPORT}. Skipping compiler optimizations.`\n : `gt-next (plugin): The GT babel compiler requires react@${BABEL_PLUGIN_SUPPORT} or newer. Skipping compiler optimizations.`;\n\nexport const babelCompilerTurbopackUnavailableWarning =\n `gt-next (plugin): The GT babel compiler is not compatible with Turbopack. ` +\n `To use compiler optimizations with Turbopack, set experimentalCompilerOptions: { type: 'swc' }.`;\n\nexport const disablingCompileTimeHashWarning = `gt-next (plugin): Compile-time hash is disabled. Compiler optimizations are inactive.`;\n\nexport const swcPluginCompatibilityChangeWarning = `gt-next (plugin): As of gt-next@6.12.4, SWC plugin support is disabled for Next.js versions prior to ${SWC_PLUGIN_SUPPORT}. Update to the latest version of Next.js.`;\n"],"mappings":"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"}
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server';
2
2
  import type { NextRequest } from 'next/server';
3
3
  import { type PathConfig } from './utils';
4
4
  export type RouteOverrides = Record<string, readonly string[]>;
5
+ export type LocaleRoutes = Record<string, readonly string[]>;
5
6
  /**
6
7
  * Middleware factory to create a Next.js middleware for i18n routing and locale detection.
7
8
  *
@@ -15,13 +16,15 @@ export type RouteOverrides = Record<string, readonly string[]>;
15
16
  * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps
16
17
  * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing
17
18
  * @param {RouteOverrides} [config.routeOverrides] - Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}
19
+ * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale
18
20
  * @returns {function} - A middleware function that processes the request and response.
19
21
  */
20
- export declare function createNextMiddleware({ localeRouting, prefixDefaultLocale, ignoreSourceMaps, pathConfig, routeOverrides, }?: {
22
+ export declare function createNextMiddleware({ localeRouting, prefixDefaultLocale, ignoreSourceMaps, pathConfig, routeOverrides, localeRoutes, }?: {
21
23
  localeRouting?: boolean;
22
24
  prefixDefaultLocale?: boolean;
23
25
  ignoreSourceMaps?: boolean;
24
26
  pathConfig?: PathConfig;
25
27
  routeOverrides?: RouteOverrides;
28
+ localeRoutes?: LocaleRoutes;
26
29
  }): (req: NextRequest) => NextResponse<unknown>;
27
30
  //# sourceMappingURL=createNextMiddleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createNextMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware-dir/createNextMiddleware.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAS/C,OAAO,EASL,KAAK,UAAU,EAEhB,MAAM,SAAS,CAAC;AAejB,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAE/D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,aAAoB,EACpB,mBAA2B,EAC3B,gBAAuB,EACvB,UAAe,EACf,cAAmB,GACpB,GAAE;IACD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;CAC5B,SAqIqB,WAAW,2BA0PrC"}
1
+ {"version":3,"file":"createNextMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware-dir/createNextMiddleware.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAS/C,OAAO,EAUL,KAAK,UAAU,EAEhB,MAAM,SAAS,CAAC;AAejB,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;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,aAAoB,EACpB,mBAA2B,EAC3B,gBAAuB,EACvB,UAAe,EACf,cAAmB,EACnB,YAAiB,GAClB,GAAE;IACD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;CACxB,SAmKqB,WAAW,2BAiTrC"}
@@ -10,7 +10,6 @@ const require_middleware_dir_matchPath = require("./matchPath.js");
10
10
  const require_middleware_dir_utils = require("./utils.js");
11
11
  let generaltranslation_internal = require("generaltranslation/internal");
12
12
  let _generaltranslation_react_core_pure = require("@generaltranslation/react-core/pure");
13
- let _generaltranslation_format = require("@generaltranslation/format");
14
13
  let generaltranslation_runtime = require("generaltranslation/runtime");
15
14
  let next_server_js = require("next/server.js");
16
15
  //#region src/middleware-dir/createNextMiddleware.ts
@@ -28,9 +27,10 @@ const NEXT_JS_SOURCE_MAP_PATH = "/__nextjs_source-map";
28
27
  * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps
29
28
  * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing
30
29
  * @param {RouteOverrides} [config.routeOverrides] - Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}
30
+ * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale
31
31
  * @returns {function} - A middleware function that processes the request and response.
32
32
  */
33
- function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, pathConfig = {}, routeOverrides = {} } = {}) {
33
+ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, pathConfig = {}, routeOverrides = {}, localeRoutes = {} } = {}) {
34
34
  const pathRegex = require_utils_pathRegex.compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);
35
35
  let envParams;
36
36
  if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) try {
@@ -39,11 +39,17 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
39
39
  console.error(`gt-next middleware:`, error);
40
40
  }
41
41
  const gt = new generaltranslation_runtime.GTRuntime({ customMapping: envParams?.customMapping });
42
- const gtServicesEnabled = process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === "true";
43
42
  const defaultLocale = envParams?.defaultLocale || generaltranslation_internal.libraryDefaultLocale;
44
- const locales = envParams?.locales || [defaultLocale];
45
- const canonicalLocales = Object.values(envParams?.customMapping || {}).filter((locale) => typeof locale === "object" && locale !== null && "code" in locale && typeof locale.code === "string" && locale.code.length > 0).map((locale) => locale.code);
46
- locales.push(...canonicalLocales);
43
+ const locales = Array.from(new Set([defaultLocale, ...envParams?.locales || []]));
44
+ const resolvedConfigLocales = /* @__PURE__ */ new Map();
45
+ const determineLocaleWithCache = (locale) => {
46
+ const cached = resolvedConfigLocales.get(locale);
47
+ if (cached !== void 0) return cached;
48
+ const resolved = gt.determineLocale(locale, locales) ?? locale;
49
+ resolvedConfigLocales.set(locale, resolved);
50
+ return resolved;
51
+ };
52
+ const resolvePathConfigLocale = process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === "true" ? determineLocaleWithCache : (locale) => locale;
47
53
  const headersAndCookies = envParams?.headersAndCookies || {};
48
54
  const localeRoutingEnabledCookieName = headersAndCookies?.localeRoutingEnabledCookieName || "generaltranslation.locale-routing-enabled";
49
55
  const referrerLocaleCookieName = headersAndCookies?.referrerLocaleCookieName || "generaltranslation.referrer-locale";
@@ -56,20 +62,23 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
56
62
  pathConfig = Object.entries(pathConfig).reduce((acc, [sharedPath, localizedPath]) => {
57
63
  if (typeof localizedPath === "string") acc[sharedPath] = localizedPath;
58
64
  else acc[sharedPath] = Object.entries(localizedPath).reduce((acc, [locale, localizedPath]) => {
59
- acc[gtServicesEnabled ? (0, _generaltranslation_format.standardizeLocale)(locale) : locale] = localizedPath;
65
+ acc[resolvePathConfigLocale(locale)] = localizedPath;
60
66
  return acc;
61
67
  }, {});
62
68
  return acc;
63
69
  }, {});
70
+ const { pathToSharedPath, defaultLocalePaths } = require_middleware_dir_createPathMatcher.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);
64
71
  routeOverrides = Object.entries(routeOverrides).reduce((acc, [locale, paths]) => {
65
- acc[gtServicesEnabled ? (0, _generaltranslation_format.standardizeLocale)(locale) : locale] = paths;
72
+ acc[resolvePathConfigLocale(locale)] = paths;
66
73
  return acc;
67
74
  }, {});
68
75
  const routeOverridePathMaps = Object.entries(routeOverrides).reduce((acc, [locale, paths]) => {
69
76
  acc[locale] = require_middleware_dir_createPathMatcher.createPathToSharedPathMap(Object.fromEntries(paths.map((path) => [path, path])), true, defaultLocale).pathToSharedPath;
70
77
  return acc;
71
78
  }, {});
72
- const { pathToSharedPath, defaultLocalePaths } = require_middleware_dir_createPathMatcher.createPathToSharedPathMap(pathConfig, prefixDefaultLocale, defaultLocale);
79
+ const localeRoutePathMaps = new Map(Object.entries(localeRoutes).map(([locale, paths]) => {
80
+ return [determineLocaleWithCache(locale), require_middleware_dir_createPathMatcher.createPathMatcher(paths.map((path) => [path, path]))];
81
+ }));
73
82
  /**
74
83
  * Processes the incoming request to determine the user's locale and sets a locale cookie.
75
84
  * Optionally redirects the user based on the locale if locale-based routing is enabled.
@@ -86,7 +95,9 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
86
95
  function middleware(req) {
87
96
  if (!require_utils_pathRegex.pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) return next_server_js.NextResponse.next();
88
97
  if (ignoreSourceMaps && req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)) return next_server_js.NextResponse.next();
89
- const { userLocale, pathnameLocale, unstandardizedPathnameLocale, clearResetCookie } = require_middleware_dir_utils.getLocaleFromRequest(req, defaultLocale, locales, localeRouting, gtServicesEnabled, prefixDefaultLocale, defaultLocalePaths, referrerLocaleCookieName, localeCookieName, resetLocaleCookieName, gt);
98
+ const { userLocale: requestedLocale, pathnameLocale: pathnameRoutingLocale, unstandardizedPathnameLocale, clearResetCookie } = require_middleware_dir_utils.getLocaleFromRequest(req, defaultLocale, locales, localeRouting, prefixDefaultLocale, defaultLocalePaths, referrerLocaleCookieName, localeCookieName, resetLocaleCookieName, gt);
99
+ let userLocale = requestedLocale;
100
+ const pathnameLocale = pathnameRoutingLocale;
90
101
  const headerList = new Headers(req.headers);
91
102
  const responseConfig = {
92
103
  originalUrl: req.nextUrl,
@@ -117,14 +128,28 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
117
128
  const standardizedPathname = pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale ? pathname.replace(new RegExp(`^/${unstandardizedPathnameLocale}`), `/${pathnameLocale}`) : pathname;
118
129
  const sharedPathMatch = require_middleware_dir_matchPath.getSharedPath(standardizedPathname, pathToSharedPath, pathnameLocale);
119
130
  const sharedPath = sharedPathMatch?.sharedPath;
131
+ const localeRoutePathMap = localeRoutePathMaps.get(userLocale);
132
+ if (userLocale !== defaultLocale && localeRoutePathMap) {
133
+ const sharedPagePath = sharedPathMatch ? require_middleware_dir_utils.replaceDynamicSegments(sharedPathMatch.matchedPathname, sharedPath || "/", sharedPathMatch.pathTemplate) : (pathnameLocale ? standardizedPathname.slice(pathnameLocale.length + 1) : standardizedPathname) || "/";
134
+ if (require_middleware_dir_matchPath.getSharedPath(sharedPagePath, localeRoutePathMap, void 0) === void 0) {
135
+ const defaultPath = sharedPath !== void 0 ? require_middleware_dir_utils.getLocalizedPath(sharedPath, defaultLocale, pathConfig) : void 0;
136
+ const fallbackPath = defaultPath !== void 0 && sharedPathMatch ? require_middleware_dir_utils.replaceDynamicSegments(sharedPathMatch.matchedPathname, defaultPath, sharedPathMatch.pathTemplate) : `/${defaultLocale}${sharedPagePath === "/" ? "" : sharedPagePath}`;
137
+ const publicFallbackPath = require_middleware_dir_pathname.applyTrailingSlash(standardizedPathname, prefixDefaultLocale ? fallbackPath : fallbackPath.slice(defaultLocale.length + 1) || "/");
138
+ userLocale = defaultLocale;
139
+ responseConfig.userLocale = defaultLocale;
140
+ const fallbackUrl = new URL(req.nextUrl);
141
+ fallbackUrl.pathname = publicFallbackPath;
142
+ if (fallbackUrl.pathname !== pathname) return getRedirectResponse(publicFallbackPath);
143
+ }
144
+ }
120
145
  const sharedPathWithParameters = sharedPathMatch !== void 0 ? require_middleware_dir_pathname.applyTrailingSlash(standardizedPathname, require_middleware_dir_utils.replaceDynamicSegments(sharedPathMatch.matchedPathname, `/${userLocale}${sharedPath}`, sharedPathMatch.pathTemplate)) : void 0;
121
146
  const localizedPath = sharedPath !== void 0 ? require_middleware_dir_utils.getLocalizedPath(sharedPath, userLocale, pathConfig) : void 0;
122
147
  const localizedPathWithParameters = localizedPath !== void 0 && sharedPathMatch !== void 0 ? require_middleware_dir_pathname.applyTrailingSlash(standardizedPathname, require_middleware_dir_utils.replaceDynamicSegments(sharedPathMatch.matchedPathname, localizedPath, sharedPathMatch.pathTemplate)) : void 0;
123
- const pagePath = (sharedPathWithParameters?.replace(new RegExp(`^/${userLocale}`), "") ?? (pathnameLocale ? standardizedPathname.replace(new RegExp(`^/${userLocale}`), "") : standardizedPathname)) || "/";
148
+ const pagePath = (sharedPathWithParameters?.slice(userLocale.length + 1) ?? (pathnameLocale ? standardizedPathname.slice(pathnameLocale.length + 1) : standardizedPathname)) || "/";
124
149
  const routeOverridePathMap = routeOverridePathMaps[userLocale];
125
150
  const routeOverridePath = (routeOverridePathMap ? require_middleware_dir_matchPath.getSharedPath(pagePath, routeOverridePathMap, void 0) : void 0) !== void 0 ? require_middleware_dir_pathname.applyTrailingSlash(standardizedPathname, `/${userLocale}/${userLocale}${pagePath === "/" ? "" : pagePath}`) : void 0;
126
151
  if (localizedPathWithParameters === void 0) {
127
- if (!prefixDefaultLocale && (0, _generaltranslation_format.isSameDialect)(userLocale, defaultLocale)) if (pathnameLocale) {
152
+ if (!prefixDefaultLocale && userLocale === defaultLocale) if (pathnameLocale) {
128
153
  if (clearResetCookie) return getRedirectResponse(pathname.replace(new RegExp(`^/${unstandardizedPathnameLocale}`), ``) || "/");
129
154
  } else return getRewriteResponse(routeOverridePath || `/${userLocale}${pathname}`);
130
155
  else if (!pathnameLocale) return getRedirectResponse(`/${userLocale}${pathname}`);
@@ -132,7 +157,7 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
132
157
  if (routeOverridePath) return getRewriteResponse(routeOverridePath);
133
158
  return getNextResponse();
134
159
  }
135
- if (!prefixDefaultLocale && (0, _generaltranslation_format.isSameDialect)(userLocale, defaultLocale)) if (pathnameLocale) {
160
+ if (!prefixDefaultLocale && userLocale === defaultLocale) if (pathnameLocale) {
136
161
  if (clearResetCookie) return getRedirectResponse(localizedPathWithParameters.replace(new RegExp(`^/${userLocale}`), ``) || "/");
137
162
  } else {
138
163
  const localizedPublicPath = localizedPathWithParameters.replace(new RegExp(`^/${userLocale}`), "") || "/";
@@ -1 +1 @@
1
- {"version":3,"file":"createNextMiddleware.js","names":["compilePathRegex","GTRuntime","libraryDefaultLocale","defaultLocaleCookieName","defaultResetLocaleCookieName","createUnsupportedLocalesWarning","createPathToSharedPathMap","pathnameMatchesRegex","NextResponse","getLocaleFromRequest","getResponse","getSharedPath","applyTrailingSlash","replaceDynamicSegments","getLocalizedPath","normalizePathname"],"sources":["../../src/middleware-dir/createNextMiddleware.ts"],"sourcesContent":["import { applyTrailingSlash } from './pathname';\nimport { isSameDialect, standardizeLocale } from '@generaltranslation/format';\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 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\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.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 * @returns {function} - A middleware function that processes the request and response.\n */\nexport function createNextMiddleware({\n localeRouting = true,\n prefixDefaultLocale = false,\n ignoreSourceMaps = true,\n pathConfig = {},\n routeOverrides = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: boolean;\n ignoreSourceMaps?: boolean;\n pathConfig?: PathConfig;\n routeOverrides?: RouteOverrides;\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 // using gt services\n const gtServicesEnabled =\n process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === 'true';\n\n // i18n config\n const defaultLocale: string =\n envParams?.defaultLocale || libraryDefaultLocale;\n const locales: string[] = envParams?.locales || [defaultLocale];\n\n // add canonical locales\n const canonicalLocales = Object.values(envParams?.customMapping || {})\n .filter(\n (locale): locale is { code: string } =>\n typeof locale === 'object' &&\n locale !== null &&\n 'code' in locale &&\n typeof locale.code === 'string' &&\n locale.code.length > 0\n )\n .map((locale) => locale.code);\n locales.push(...canonicalLocales);\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 // Standardize pathConfig paths\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[gtServicesEnabled ? standardizeLocale(locale) : locale] =\n localizedPath;\n return acc;\n }, {});\n }\n return acc;\n },\n {}\n );\n\n // Standardize routeOverrides locales\n routeOverrides = Object.entries(routeOverrides).reduce<RouteOverrides>(\n (acc, [locale, paths]) => {\n acc[gtServicesEnabled ? standardizeLocale(locale) : 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 // Create the path mapping\n const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(\n pathConfig,\n prefixDefaultLocale,\n defaultLocale\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,\n pathnameLocale,\n unstandardizedPathnameLocale,\n clearResetCookie,\n } = getLocaleFromRequest(\n req,\n defaultLocale,\n locales,\n localeRouting,\n gtServicesEnabled,\n prefixDefaultLocale,\n defaultLocalePaths,\n referrerLocaleCookieName,\n localeCookieName,\n resetLocaleCookieName,\n gt\n );\n\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 getResponse({ responsePath, type: 'redirect', ...responseConfig });\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 // 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?.replace(new RegExp(`^/${userLocale}`), '') ??\n (pathnameLocale\n ? standardizedPathname.replace(new RegExp(`^/${userLocale}`), '')\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 && isSameDialect(userLocale, defaultLocale)) {\n if (pathnameLocale) {\n // REDIRECT CASE: used setLocale (/fr/customers -> /customers) (/en/customers -> /customers)\n if (clearResetCookie) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\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 && isSameDialect(userLocale, defaultLocale)) {\n // --- CASE: remove defaultLocale prefix --- //\n\n if (pathnameLocale) {\n // REDIRECT CASE: remove locale prefix when setLocale is used (/en/blog -> /blog) (/fr/fr-about -> /en-about)\n if (clearResetCookie) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n const localizedPublicPath =\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ''\n ) || '/';\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":";;;;;;;;;;;;;;;;AAgCA,MAAM,0BAA0B;;;;;;;;;;;;;;;;AA0BhC,SAAgB,qBAAqB,EACnC,gBAAgB,MAChB,sBAAsB,OACtB,mBAAmB,MACnB,aAAa,EAAE,EACf,iBAAiB,EAAE,KAOjB,EAAE,EAAE;CACN,MAAM,YAAYA,wBAAAA,iBAChB,QAAQ,IAAI,+BACb;CAGD,IAAI;AACJ,KAAI,QAAQ,IAAI,uCACd,KAAI;AACF,cAAY,KAAK,MACf,QAAQ,IAAI,uCACb;UACM,OAAO;AACd,UAAQ,MAAM,uBAAuB,MAAM;;CAK/C,MAAM,KAAK,IAAIC,2BAAAA,UAAU,EACvB,eAAe,WAAW,eAC3B,CAAC;CAGF,MAAM,oBACJ,QAAQ,IAAI,4CAA4C;CAG1D,MAAM,gBACJ,WAAW,iBAAiBC,4BAAAA;CAC9B,MAAM,UAAoB,WAAW,WAAW,CAAC,cAAc;CAG/D,MAAM,mBAAmB,OAAO,OAAO,WAAW,iBAAiB,EAAE,CAAC,CACnE,QACE,WACC,OAAO,WAAW,YAClB,WAAW,QACX,UAAU,UACV,OAAO,OAAO,SAAS,YACvB,OAAO,KAAK,SAAS,EACxB,CACA,KAAK,WAAW,OAAO,KAAK;AAC/B,SAAQ,KAAK,GAAG,iBAAiB;CAGjC,MAAM,oBAAoB,WAAW,qBAAqB,EAAE;CAC5D,MAAM,iCACJ,mBAAmB,kCAAA;CAErB,MAAM,2BACJ,mBAAmB,4BAAA;CAErB,MAAM,mBACJ,mBAAmB,oBAAoBC,oCAAAA;CACzC,MAAM,wBACJ,mBAAmB,yBAAyBC,oCAAAA;CAC9C,MAAM,mBACJ,mBAAmB,oBAAA;AAErB,KAAI,CAAC,GAAG,cAAc,cAAc,CAClC,OAAM,IAAI,MACR,sCAAsC,cAAc,0BACrD;CAEH,MAAM,iBAAiB,QAAQ,QAAQ,WAAW,CAAC,GAAG,cAAc,OAAO,CAAC;AAC5E,KAAI,eAAe,OACjB,SAAQ,KAAKC,0BAAAA,gCAAgC,eAAe,CAAC;AAK/D,cAAa,OAAO,QAAQ,WAAW,CAAC,QACrC,KAAK,CAAC,YAAY,mBAAmB;AACpC,MAAI,OAAO,kBAAkB,SAC3B,KAAI,cAAc;MAElB,KAAI,cAAc,OAAO,QAAQ,cAAc,CAAC,QAE5C,KAAK,CAAC,QAAQ,mBAAmB;AACnC,OAAI,qBAAA,GAAA,2BAAA,mBAAsC,OAAO,GAAG,UAClD;AACF,UAAO;KACN,EAAE,CAAC;AAER,SAAO;IAET,EAAE,CACH;AAGD,kBAAiB,OAAO,QAAQ,eAAe,CAAC,QAC7C,KAAK,CAAC,QAAQ,WAAW;AACxB,MAAI,qBAAA,GAAA,2BAAA,mBAAsC,OAAO,GAAG,UAAU;AAC9D,SAAO;IAET,EAAE,CACH;CAGD,MAAM,wBAAwB,OAAO,QAAQ,eAAe,CAAC,QAE1D,KAAK,CAAC,QAAQ,WAAW;AAI1B,MAAI,UAAUC,yCAAAA,0BAHa,OAAO,YAChC,MAAM,KAAK,SAAS,CAAC,MAAM,KAAK,CAAC,CAGf,EAClB,MACA,cACD,CAAC;AACF,SAAO;IACN,EAAE,CAAC;CAGN,MAAM,EAAE,kBAAkB,uBAAuBA,yCAAAA,0BAC/C,YACA,qBACA,cACD;;;;;;;;;;;;;;CAeD,SAAS,WAAW,KAAkB;AACpC,MAAI,CAACC,wBAAAA,qBAAqB,IAAI,QAAQ,UAAU,UAAU,CACxD,QAAOC,eAAAA,aAAa,MAAM;AAI5B,MACE,oBACA,IAAI,QAAQ,SAAS,WAAW,wBAAwB,CAExD,QAAOA,eAAAA,aAAa,MAAM;EAK5B,MAAM,EACJ,YACA,gBACA,8BACA,qBACEC,6BAAAA,qBACF,KACA,eACA,SACA,eACA,mBACA,qBACA,oBACA,0BACA,kBACA,uBACA,GACD;EAED,MAAM,aAAa,IAAI,QAAQ,IAAI,QAAQ;EAE3C,MAAM,iBAA+C;GACnD,aAAa,IAAI;GACjB;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EAED,MAAM,sBAAsB,iBAC1BC,6BAAAA,YAAY;GAAE;GAAc,MAAM;GAAW,GAAG;GAAgB,CAAC;EAEnE,MAAM,uBAAuB,iBAC3BA,6BAAAA,YAAY;GAAE;GAAc,MAAM;GAAY,GAAG;GAAgB,CAAC;EAEpE,MAAM,wBACJA,6BAAAA,YAAY;GAAE,MAAM;GAAQ,GAAG;GAAgB,CAAC;AAElD,MAAI,eAAe;GAIjB,MAAM,EAAE,aAAa,IAAI;GAGzB,MAAM,uBACJ,kBAAkB,mBAAmB,+BACjC,SAAS,QACP,IAAI,OAAO,KAAK,+BAA+B,EAC/C,IAAI,iBACL,GACD;GAGN,MAAM,kBAAkBC,iCAAAA,cACtB,sBACA,kBACA,eACD;GACD,MAAM,aAAa,iBAAiB;GAGpC,MAAM,2BACJ,oBAAoB,KAAA,IAChBC,gCAAAA,mBACE,sBACAC,6BAAAA,uBACE,gBAAgB,iBAChB,IAAI,aAAa,cACjB,gBAAgB,aACjB,CACF,GACD,KAAA;GAGN,MAAM,gBACJ,eAAe,KAAA,IACXC,6BAAAA,iBAAiB,YAAY,YAAY,WAAW,GACpD,KAAA;GAGN,MAAM,8BACJ,kBAAkB,KAAA,KAAa,oBAAoB,KAAA,IAC/CF,gCAAAA,mBACE,sBACAC,6BAAAA,uBACE,gBAAgB,iBAChB,eACA,gBAAgB,aACjB,CACF,GACD,KAAA;GAEN,MAAM,YACH,0BAA0B,QAAQ,IAAI,OAAO,KAAK,aAAa,EAAE,GAAG,KAClE,iBACG,qBAAqB,QAAQ,IAAI,OAAO,KAAK,aAAa,EAAE,GAAG,GAC/D,0BACN;GACF,MAAM,uBAAuB,sBAAsB;GAInD,MAAM,qBAHqB,uBACvBF,iCAAAA,cAAc,UAAU,sBAAsB,KAAA,EAAU,GACxD,KAAA,OAEqB,KAAA,IACnBC,gCAAAA,mBACE,sBACA,IAAI,WAAW,GAAG,aAAa,aAAa,MAAM,KAAK,WACxD,GACD,KAAA;AAMN,OAAI,gCAAgC,KAAA,GAAW;AAG7C,QAAI,CAAC,wBAAA,GAAA,2BAAA,eAAqC,YAAY,cAAc,CAClE,KAAI;SAEE,iBACF,QAAO,oBACL,SAAS,QACP,IAAI,OAAO,KAAK,+BAA+B,EAC/C,GACD,IAAI,IACN;UAIH,QAAO,mBACL,qBAAqB,IAAI,aAAa,WACvC;aAMI,CAAC,eACR,QAAO,oBAAoB,IAAI,aAAa,WAAW;AAIzD,QAAI,kBAAkB,eAAe,6BACnC,QAAO,oBACL,SAAS,QACP,IAAI,OAAO,KAAK,+BAA+B,EAC/C,IAAI,aACL,CACF;AAIH,QAAI,kBACF,QAAO,mBAAmB,kBAAkB;AAE9C,WAAO,iBAAiB;;AAK1B,OAAI,CAAC,wBAAA,GAAA,2BAAA,eAAqC,YAAY,cAAc,CAGlE,KAAI;QAEE,iBACF,QAAO,oBACL,4BAA4B,QAC1B,IAAI,OAAO,KAAK,aAAa,EAC7B,GACD,IAAI,IACN;UAEE;IACL,MAAM,sBACJ,4BAA4B,QAC1B,IAAI,OAAO,KAAK,aAAa,EAC7B,GACD,IAAI;AAGP,QACE,CAAC,kBACDG,gCAAAA,kBAAkB,oBAAoB,KACpCA,gCAAAA,kBAAkB,SAAS,CAE7B,QAAO,oBAAoB,oBAAoB;AAIjD,WAAO,mBACL,qBAAsB,yBACvB;;AAOL,OACEA,gCAAAA,kBAAkB,SAAS,KAC3BA,gCAAAA,kBAAkB,4BAA4B,CAE9C,QAAO,oBAAoB,4BAA4B;AAGzD,OAAI,kBACF,QAAO,mBAAmB,kBAAkB;GAM9C,MAAM,aAAa,IAAI,IACrB,0BACA,IAAI,QACL;AACD,OACE,IAAI,QAAQ,aAAa,WAAW,SAGpC,QAAO,mBAAmB,yBAAmC;;AAKjE,SAAO,iBAAiB;;AAG1B,QAAO"}
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.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 ignoreSourceMaps = true,\n pathConfig = {},\n routeOverrides = {},\n localeRoutes = {},\n}: {\n localeRouting?: boolean;\n prefixDefaultLocale?: 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 );\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 getResponse({ responsePath, type: 'redirect', ...responseConfig });\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: used setLocale (/fr/customers -> /customers) (/en/customers -> /customers)\n if (clearResetCookie) {\n return getRedirectResponse(\n pathname.replace(\n new RegExp(`^/${unstandardizedPathnameLocale}`),\n ``\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: remove locale prefix when setLocale is used (/en/blog -> /blog) (/fr/fr-about -> /en-about)\n if (clearResetCookie) {\n return getRedirectResponse(\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ``\n ) || '/'\n );\n }\n } else {\n const localizedPublicPath =\n localizedPathWithParameters.replace(\n new RegExp(`^/${userLocale}`),\n ''\n ) || '/';\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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"}
@@ -3,12 +3,11 @@ import "../utils/cookies.mjs";
3
3
  import { compilePathRegex, pathnameMatchesRegex } from "../utils/pathRegex.mjs";
4
4
  import { applyTrailingSlash, normalizePathname } from "./pathname.mjs";
5
5
  import { createUnsupportedLocalesWarning } from "../errors/middleware.mjs";
6
- import { createPathToSharedPathMap } from "./createPathMatcher.mjs";
6
+ import { createPathMatcher, createPathToSharedPathMap } from "./createPathMatcher.mjs";
7
7
  import { getSharedPath } from "./matchPath.mjs";
8
8
  import { getLocaleFromRequest, getLocalizedPath, getResponse, replaceDynamicSegments } from "./utils.mjs";
9
9
  import { libraryDefaultLocale } from "generaltranslation/internal";
10
10
  import { defaultLocaleCookieName, defaultResetLocaleCookieName } from "@generaltranslation/react-core/pure";
11
- import { isSameDialect, standardizeLocale } from "@generaltranslation/format";
12
11
  import { GTRuntime } from "generaltranslation/runtime";
13
12
  import { NextResponse } from "next/server.js";
14
13
  //#region src/middleware-dir/createNextMiddleware.ts
@@ -26,9 +25,10 @@ const NEXT_JS_SOURCE_MAP_PATH = "/__nextjs_source-map";
26
25
  * @param {boolean} [config.ignoreSourceMaps=true] - Flag to enable or disable ignoring source maps
27
26
  * @param {PathConfig} [config.pathConfig] - Path configuration for locale routing
28
27
  * @param {RouteOverrides} [config.routeOverrides] - Locale-relative paths to rewrite from /{locale}/{path} to /{locale}/{locale}/{path}
28
+ * @param {LocaleRoutes} [config.localeRoutes] - Shared paths available per locale; other paths fall back to the default locale
29
29
  * @returns {function} - A middleware function that processes the request and response.
30
30
  */
31
- function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, pathConfig = {}, routeOverrides = {} } = {}) {
31
+ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = false, ignoreSourceMaps = true, pathConfig = {}, routeOverrides = {}, localeRoutes = {} } = {}) {
32
32
  const pathRegex = compilePathRegex(process.env._GENERALTRANSLATION_PATH_REGEX);
33
33
  let envParams;
34
34
  if (process.env._GENERALTRANSLATION_I18N_CONFIG_PARAMS) try {
@@ -37,11 +37,17 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
37
37
  console.error(`gt-next middleware:`, error);
38
38
  }
39
39
  const gt = new GTRuntime({ customMapping: envParams?.customMapping });
40
- const gtServicesEnabled = process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === "true";
41
40
  const defaultLocale = envParams?.defaultLocale || libraryDefaultLocale;
42
- const locales = envParams?.locales || [defaultLocale];
43
- const canonicalLocales = Object.values(envParams?.customMapping || {}).filter((locale) => typeof locale === "object" && locale !== null && "code" in locale && typeof locale.code === "string" && locale.code.length > 0).map((locale) => locale.code);
44
- locales.push(...canonicalLocales);
41
+ const locales = Array.from(new Set([defaultLocale, ...envParams?.locales || []]));
42
+ const resolvedConfigLocales = /* @__PURE__ */ new Map();
43
+ const determineLocaleWithCache = (locale) => {
44
+ const cached = resolvedConfigLocales.get(locale);
45
+ if (cached !== void 0) return cached;
46
+ const resolved = gt.determineLocale(locale, locales) ?? locale;
47
+ resolvedConfigLocales.set(locale, resolved);
48
+ return resolved;
49
+ };
50
+ const resolvePathConfigLocale = process.env._GENERALTRANSLATION_GT_SERVICES_ENABLED === "true" ? determineLocaleWithCache : (locale) => locale;
45
51
  const headersAndCookies = envParams?.headersAndCookies || {};
46
52
  const localeRoutingEnabledCookieName = headersAndCookies?.localeRoutingEnabledCookieName || "generaltranslation.locale-routing-enabled";
47
53
  const referrerLocaleCookieName = headersAndCookies?.referrerLocaleCookieName || "generaltranslation.referrer-locale";
@@ -54,20 +60,23 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
54
60
  pathConfig = Object.entries(pathConfig).reduce((acc, [sharedPath, localizedPath]) => {
55
61
  if (typeof localizedPath === "string") acc[sharedPath] = localizedPath;
56
62
  else acc[sharedPath] = Object.entries(localizedPath).reduce((acc, [locale, localizedPath]) => {
57
- acc[gtServicesEnabled ? standardizeLocale(locale) : locale] = localizedPath;
63
+ acc[resolvePathConfigLocale(locale)] = localizedPath;
58
64
  return acc;
59
65
  }, {});
60
66
  return acc;
61
67
  }, {});
68
+ 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);
62
69
  routeOverrides = Object.entries(routeOverrides).reduce((acc, [locale, paths]) => {
63
- acc[gtServicesEnabled ? standardizeLocale(locale) : locale] = paths;
70
+ acc[resolvePathConfigLocale(locale)] = paths;
64
71
  return acc;
65
72
  }, {});
66
73
  const routeOverridePathMaps = Object.entries(routeOverrides).reduce((acc, [locale, paths]) => {
67
74
  acc[locale] = createPathToSharedPathMap(Object.fromEntries(paths.map((path) => [path, path])), true, defaultLocale).pathToSharedPath;
68
75
  return acc;
69
76
  }, {});
70
- const { pathToSharedPath, defaultLocalePaths } = createPathToSharedPathMap(pathConfig, prefixDefaultLocale, defaultLocale);
77
+ const localeRoutePathMaps = new Map(Object.entries(localeRoutes).map(([locale, paths]) => {
78
+ return [determineLocaleWithCache(locale), createPathMatcher(paths.map((path) => [path, path]))];
79
+ }));
71
80
  /**
72
81
  * Processes the incoming request to determine the user's locale and sets a locale cookie.
73
82
  * Optionally redirects the user based on the locale if locale-based routing is enabled.
@@ -84,7 +93,9 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
84
93
  function middleware(req) {
85
94
  if (!pathnameMatchesRegex(req.nextUrl.pathname, pathRegex)) return NextResponse.next();
86
95
  if (ignoreSourceMaps && req.nextUrl.pathname.startsWith(NEXT_JS_SOURCE_MAP_PATH)) return NextResponse.next();
87
- const { userLocale, pathnameLocale, unstandardizedPathnameLocale, clearResetCookie } = getLocaleFromRequest(req, defaultLocale, locales, localeRouting, gtServicesEnabled, prefixDefaultLocale, defaultLocalePaths, referrerLocaleCookieName, localeCookieName, resetLocaleCookieName, gt);
96
+ const { userLocale: requestedLocale, pathnameLocale: pathnameRoutingLocale, unstandardizedPathnameLocale, clearResetCookie } = getLocaleFromRequest(req, defaultLocale, locales, localeRouting, prefixDefaultLocale, defaultLocalePaths, referrerLocaleCookieName, localeCookieName, resetLocaleCookieName, gt);
97
+ let userLocale = requestedLocale;
98
+ const pathnameLocale = pathnameRoutingLocale;
88
99
  const headerList = new Headers(req.headers);
89
100
  const responseConfig = {
90
101
  originalUrl: req.nextUrl,
@@ -115,14 +126,28 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
115
126
  const standardizedPathname = pathnameLocale && pathnameLocale !== unstandardizedPathnameLocale ? pathname.replace(new RegExp(`^/${unstandardizedPathnameLocale}`), `/${pathnameLocale}`) : pathname;
116
127
  const sharedPathMatch = getSharedPath(standardizedPathname, pathToSharedPath, pathnameLocale);
117
128
  const sharedPath = sharedPathMatch?.sharedPath;
129
+ const localeRoutePathMap = localeRoutePathMaps.get(userLocale);
130
+ if (userLocale !== defaultLocale && localeRoutePathMap) {
131
+ const sharedPagePath = sharedPathMatch ? replaceDynamicSegments(sharedPathMatch.matchedPathname, sharedPath || "/", sharedPathMatch.pathTemplate) : (pathnameLocale ? standardizedPathname.slice(pathnameLocale.length + 1) : standardizedPathname) || "/";
132
+ if (getSharedPath(sharedPagePath, localeRoutePathMap, void 0) === void 0) {
133
+ const defaultPath = sharedPath !== void 0 ? getLocalizedPath(sharedPath, defaultLocale, pathConfig) : void 0;
134
+ const fallbackPath = defaultPath !== void 0 && sharedPathMatch ? replaceDynamicSegments(sharedPathMatch.matchedPathname, defaultPath, sharedPathMatch.pathTemplate) : `/${defaultLocale}${sharedPagePath === "/" ? "" : sharedPagePath}`;
135
+ const publicFallbackPath = applyTrailingSlash(standardizedPathname, prefixDefaultLocale ? fallbackPath : fallbackPath.slice(defaultLocale.length + 1) || "/");
136
+ userLocale = defaultLocale;
137
+ responseConfig.userLocale = defaultLocale;
138
+ const fallbackUrl = new URL(req.nextUrl);
139
+ fallbackUrl.pathname = publicFallbackPath;
140
+ if (fallbackUrl.pathname !== pathname) return getRedirectResponse(publicFallbackPath);
141
+ }
142
+ }
118
143
  const sharedPathWithParameters = sharedPathMatch !== void 0 ? applyTrailingSlash(standardizedPathname, replaceDynamicSegments(sharedPathMatch.matchedPathname, `/${userLocale}${sharedPath}`, sharedPathMatch.pathTemplate)) : void 0;
119
144
  const localizedPath = sharedPath !== void 0 ? getLocalizedPath(sharedPath, userLocale, pathConfig) : void 0;
120
145
  const localizedPathWithParameters = localizedPath !== void 0 && sharedPathMatch !== void 0 ? applyTrailingSlash(standardizedPathname, replaceDynamicSegments(sharedPathMatch.matchedPathname, localizedPath, sharedPathMatch.pathTemplate)) : void 0;
121
- const pagePath = (sharedPathWithParameters?.replace(new RegExp(`^/${userLocale}`), "") ?? (pathnameLocale ? standardizedPathname.replace(new RegExp(`^/${userLocale}`), "") : standardizedPathname)) || "/";
146
+ const pagePath = (sharedPathWithParameters?.slice(userLocale.length + 1) ?? (pathnameLocale ? standardizedPathname.slice(pathnameLocale.length + 1) : standardizedPathname)) || "/";
122
147
  const routeOverridePathMap = routeOverridePathMaps[userLocale];
123
148
  const routeOverridePath = (routeOverridePathMap ? getSharedPath(pagePath, routeOverridePathMap, void 0) : void 0) !== void 0 ? applyTrailingSlash(standardizedPathname, `/${userLocale}/${userLocale}${pagePath === "/" ? "" : pagePath}`) : void 0;
124
149
  if (localizedPathWithParameters === void 0) {
125
- if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) if (pathnameLocale) {
150
+ if (!prefixDefaultLocale && userLocale === defaultLocale) if (pathnameLocale) {
126
151
  if (clearResetCookie) return getRedirectResponse(pathname.replace(new RegExp(`^/${unstandardizedPathnameLocale}`), ``) || "/");
127
152
  } else return getRewriteResponse(routeOverridePath || `/${userLocale}${pathname}`);
128
153
  else if (!pathnameLocale) return getRedirectResponse(`/${userLocale}${pathname}`);
@@ -130,7 +155,7 @@ function createNextMiddleware({ localeRouting = true, prefixDefaultLocale = fals
130
155
  if (routeOverridePath) return getRewriteResponse(routeOverridePath);
131
156
  return getNextResponse();
132
157
  }
133
- if (!prefixDefaultLocale && isSameDialect(userLocale, defaultLocale)) if (pathnameLocale) {
158
+ if (!prefixDefaultLocale && userLocale === defaultLocale) if (pathnameLocale) {
134
159
  if (clearResetCookie) return getRedirectResponse(localizedPathWithParameters.replace(new RegExp(`^/${userLocale}`), ``) || "/");
135
160
  } else {
136
161
  const localizedPublicPath = localizedPathWithParameters.replace(new RegExp(`^/${userLocale}`), "") || "/";