next-intl 3.21.1 → 3.21.2-canary.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 (129) hide show
  1. package/dist/development/middleware/middleware.js +19 -17
  2. package/dist/development/middleware/resolveLocale.js +20 -34
  3. package/dist/development/middleware/syncCookie.js +8 -7
  4. package/dist/development/navigation/react-client/ClientLink.js +2 -2
  5. package/dist/development/navigation/react-client/createLocalizedPathnamesNavigation.js +6 -1
  6. package/dist/development/navigation/react-client/createNavigation.js +83 -0
  7. package/dist/development/navigation/react-client/createSharedPathnamesNavigation.js +6 -1
  8. package/dist/development/navigation/react-client/useBasePathname.js +0 -14
  9. package/dist/development/navigation/react-client/useBaseRouter.js +3 -3
  10. package/dist/development/navigation/react-server/ServerLink.js +4 -2
  11. package/dist/development/navigation/react-server/createLocalizedPathnamesNavigation.js +5 -4
  12. package/dist/development/navigation/react-server/createNavigation.js +30 -0
  13. package/dist/development/navigation/react-server/createSharedPathnamesNavigation.js +2 -0
  14. package/dist/development/navigation/react-server/redirects.js +2 -2
  15. package/dist/development/navigation/shared/BaseLink.js +30 -26
  16. package/dist/development/navigation/shared/LegacyBaseLink.js +57 -0
  17. package/dist/development/navigation/shared/createSharedNavigationFns.js +148 -0
  18. package/dist/development/navigation/shared/redirects.js +3 -0
  19. package/dist/development/navigation/shared/syncLocaleCookie.js +26 -5
  20. package/dist/development/navigation/shared/utils.js +40 -1
  21. package/dist/development/navigation.react-client.js +2 -0
  22. package/dist/development/navigation.react-server.js +2 -0
  23. package/dist/development/react-client/index.js +0 -2
  24. package/dist/development/routing/config.js +18 -1
  25. package/dist/development/server/react-server/RequestLocale.js +15 -25
  26. package/dist/development/server/react-server/RequestLocaleCache.js +23 -0
  27. package/dist/development/server/react-server/RequestLocaleLegacy.js +43 -0
  28. package/dist/development/server/react-server/getConfig.js +15 -17
  29. package/dist/development/server/react-server/getRequestConfig.js +1 -1
  30. package/dist/development/server.react-server.js +2 -2
  31. package/dist/development/shared/constants.js +0 -9
  32. package/dist/esm/middleware/middleware.js +1 -1
  33. package/dist/esm/middleware/resolveLocale.js +1 -1
  34. package/dist/esm/middleware/syncCookie.js +1 -1
  35. package/dist/esm/navigation/react-client/ClientLink.js +1 -1
  36. package/dist/esm/navigation/react-client/createLocalizedPathnamesNavigation.js +1 -1
  37. package/dist/esm/navigation/react-client/createNavigation.js +1 -0
  38. package/dist/esm/navigation/react-client/createSharedPathnamesNavigation.js +1 -1
  39. package/dist/esm/navigation/react-client/useBasePathname.js +0 -1
  40. package/dist/esm/navigation/react-client/useBaseRouter.js +1 -1
  41. package/dist/esm/navigation/react-server/ServerLink.js +1 -1
  42. package/dist/esm/navigation/react-server/createLocalizedPathnamesNavigation.js +1 -1
  43. package/dist/esm/navigation/react-server/createNavigation.js +1 -0
  44. package/dist/esm/navigation/react-server/createSharedPathnamesNavigation.js +1 -1
  45. package/dist/esm/navigation/react-server/redirects.js +1 -1
  46. package/dist/esm/navigation/shared/BaseLink.js +1 -1
  47. package/dist/esm/navigation/shared/LegacyBaseLink.js +2 -0
  48. package/dist/esm/navigation/shared/createSharedNavigationFns.js +1 -0
  49. package/dist/esm/navigation/shared/syncLocaleCookie.js +1 -1
  50. package/dist/esm/navigation/shared/utils.js +1 -1
  51. package/dist/esm/navigation.react-client.js +1 -1
  52. package/dist/esm/navigation.react-server.js +1 -1
  53. package/dist/esm/routing/config.js +1 -1
  54. package/dist/esm/server/react-server/RequestLocale.js +1 -1
  55. package/dist/esm/server/react-server/RequestLocaleCache.js +1 -0
  56. package/dist/esm/server/react-server/RequestLocaleLegacy.js +1 -0
  57. package/dist/esm/server/react-server/getConfig.js +1 -1
  58. package/dist/esm/server.react-server.js +1 -1
  59. package/dist/esm/shared/constants.js +1 -1
  60. package/dist/production/middleware/middleware.js +1 -1
  61. package/dist/production/middleware/resolveLocale.js +1 -1
  62. package/dist/production/middleware/syncCookie.js +1 -1
  63. package/dist/production/navigation/react-client/ClientLink.js +1 -1
  64. package/dist/production/navigation/react-client/createLocalizedPathnamesNavigation.js +1 -1
  65. package/dist/production/navigation/react-client/createNavigation.js +1 -0
  66. package/dist/production/navigation/react-client/createSharedPathnamesNavigation.js +1 -1
  67. package/dist/production/navigation/react-client/useBasePathname.js +0 -1
  68. package/dist/production/navigation/react-client/useBaseRouter.js +1 -1
  69. package/dist/production/navigation/react-server/ServerLink.js +1 -1
  70. package/dist/production/navigation/react-server/createLocalizedPathnamesNavigation.js +1 -1
  71. package/dist/production/navigation/react-server/createNavigation.js +1 -0
  72. package/dist/production/navigation/react-server/createSharedPathnamesNavigation.js +1 -1
  73. package/dist/production/navigation/react-server/redirects.js +1 -1
  74. package/dist/production/navigation/shared/BaseLink.js +1 -1
  75. package/dist/production/navigation/shared/LegacyBaseLink.js +2 -0
  76. package/dist/production/navigation/shared/createSharedNavigationFns.js +1 -0
  77. package/dist/production/navigation/shared/syncLocaleCookie.js +1 -1
  78. package/dist/production/navigation/shared/utils.js +1 -1
  79. package/dist/production/navigation.react-client.js +1 -1
  80. package/dist/production/navigation.react-server.js +1 -1
  81. package/dist/production/routing/config.js +1 -1
  82. package/dist/production/server/react-server/RequestLocale.js +1 -1
  83. package/dist/production/server/react-server/RequestLocaleCache.js +1 -0
  84. package/dist/production/server/react-server/RequestLocaleLegacy.js +1 -0
  85. package/dist/production/server/react-server/getConfig.js +1 -1
  86. package/dist/production/server.react-server.js +1 -1
  87. package/dist/production/shared/constants.js +1 -1
  88. package/dist/types/src/middleware/getAlternateLinksHeaderValue.d.ts +3 -3
  89. package/dist/types/src/middleware/middleware.d.ts +11 -3
  90. package/dist/types/src/middleware/resolveLocale.d.ts +2 -3
  91. package/dist/types/src/middleware/syncCookie.d.ts +2 -1
  92. package/dist/types/src/middleware/utils.d.ts +4 -4
  93. package/dist/types/src/navigation/createNavigation.test.d.ts +1 -0
  94. package/dist/types/src/navigation/react-client/ClientLink.d.ts +6 -6
  95. package/dist/types/src/navigation/react-client/createLocalizedPathnamesNavigation.d.ts +17 -5
  96. package/dist/types/src/navigation/react-client/createNavigation.d.ts +467 -0
  97. package/dist/types/src/navigation/react-client/createNavigation.test.d.ts +1 -0
  98. package/dist/types/src/navigation/react-client/createSharedPathnamesNavigation.d.ts +9 -5
  99. package/dist/types/src/navigation/react-client/index.d.ts +1 -0
  100. package/dist/types/src/navigation/react-client/redirects.d.ts +4 -4
  101. package/dist/types/src/navigation/react-client/useBasePathname.d.ts +2 -15
  102. package/dist/types/src/navigation/react-client/useBaseRouter.d.ts +3 -2
  103. package/dist/types/src/navigation/react-server/ServerLink.d.ts +5 -5
  104. package/dist/types/src/navigation/react-server/createLocalizedPathnamesNavigation.d.ts +14 -5
  105. package/dist/types/src/navigation/react-server/createNavigation.d.ts +385 -0
  106. package/dist/types/src/navigation/react-server/createNavigation.test.d.ts +1 -0
  107. package/dist/types/src/navigation/react-server/createSharedPathnamesNavigation.d.ts +3 -3
  108. package/dist/types/src/navigation/react-server/index.d.ts +1 -0
  109. package/dist/types/src/navigation/react-server/redirects.d.ts +4 -4
  110. package/dist/types/src/navigation/shared/BaseLink.d.ts +13 -6
  111. package/dist/types/src/navigation/shared/LegacyBaseLink.d.ts +12 -0
  112. package/dist/types/src/navigation/shared/createSharedNavigationFns.d.ts +385 -0
  113. package/dist/types/src/navigation/shared/redirects.d.ts +5 -5
  114. package/dist/types/src/navigation/shared/syncLocaleCookie.d.ts +2 -1
  115. package/dist/types/src/navigation/shared/utils.d.ts +10 -3
  116. package/dist/types/src/routing/config.d.ts +46 -11
  117. package/dist/types/src/routing/defineRouting.d.ts +2 -2
  118. package/dist/types/src/routing/types.d.ts +4 -4
  119. package/dist/types/src/server/react-server/RequestLocale.d.ts +1 -2
  120. package/dist/types/src/server/react-server/RequestLocaleCache.d.ts +2 -0
  121. package/dist/types/src/server/react-server/RequestLocaleLegacy.d.ts +1 -0
  122. package/dist/types/src/server/react-server/createRequestConfig.d.ts +2 -3
  123. package/dist/types/src/server/react-server/getRequestConfig.d.ts +32 -6
  124. package/dist/types/src/server/react-server/index.d.ts +1 -1
  125. package/dist/types/src/shared/constants.d.ts +0 -3
  126. package/dist/types/src/shared/types.d.ts +3 -0
  127. package/dist/types/src/shared/utils.d.ts +2 -2
  128. package/package.json +3 -3
  129. package/dist/types/src/middleware/config.d.ts +0 -7
@@ -0,0 +1,57 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
7
+ var navigation = require('next/navigation');
8
+ var React = require('react');
9
+ var useLocale = require('../../react-client/useLocale.js');
10
+ var utils = require('../../shared/utils.js');
11
+ var BaseLink = require('./BaseLink.js');
12
+
13
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
+
15
+ var React__default = /*#__PURE__*/_interopDefault(React);
16
+
17
+ function LegacyBaseLink(_ref, ref) {
18
+ let {
19
+ href,
20
+ locale,
21
+ localeCookie,
22
+ localePrefixMode,
23
+ prefix,
24
+ ...rest
25
+ } = _ref;
26
+ // The types aren't entirely correct here. Outside of Next.js
27
+ // `useParams` can be called, but the return type is `null`.
28
+ const pathname = navigation.usePathname();
29
+ const curLocale = useLocale.default();
30
+ const isChangingLocale = locale !== curLocale;
31
+ const [localizedHref, setLocalizedHref] = React.useState(() => utils.isLocalizableHref(href) && (localePrefixMode !== 'never' || isChangingLocale) ?
32
+ // For the `localePrefix: 'as-needed' strategy, the href shouldn't
33
+ // be prefixed if the locale is the default locale. To determine this, we
34
+ // need a) the default locale and b) the information if we use prefixed
35
+ // routing. The default locale can vary by domain, therefore during the
36
+ // RSC as well as the SSR render, we can't determine the default locale
37
+ // statically. Therefore we always prefix the href since this will
38
+ // always result in a valid URL, even if it might cause a redirect. This
39
+ // is better than pointing to a non-localized href during the server
40
+ // render, which would potentially be wrong. The final href is
41
+ // determined in the effect below.
42
+ utils.prefixHref(href, prefix) : href);
43
+ React.useEffect(() => {
44
+ if (!pathname) return;
45
+ setLocalizedHref(utils.localizeHref(href, locale, curLocale, pathname, prefix));
46
+ }, [curLocale, href, locale, pathname, prefix]);
47
+ return /*#__PURE__*/React__default.default.createElement(BaseLink.default, _rollupPluginBabelHelpers.extends({
48
+ ref: ref,
49
+ href: localizedHref,
50
+ locale: locale,
51
+ localeCookie: localeCookie
52
+ }, rest));
53
+ }
54
+ const LegacyBaseLinkWithRef = /*#__PURE__*/React.forwardRef(LegacyBaseLink);
55
+ LegacyBaseLinkWithRef.displayName = 'ClientLink';
56
+
57
+ exports.default = LegacyBaseLinkWithRef;
@@ -0,0 +1,148 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
6
+ var navigation = require('next/navigation');
7
+ var React = require('react');
8
+ var config = require('../../routing/config.js');
9
+ var utils$1 = require('../../shared/utils.js');
10
+ var BaseLink = require('./BaseLink.js');
11
+ var utils = require('./utils.js');
12
+
13
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
+
15
+ var React__default = /*#__PURE__*/_interopDefault(React);
16
+
17
+ /**
18
+ * Shared implementations for `react-server` and `react-client`
19
+ */
20
+ function createSharedNavigationFns(getLocale, routing) {
21
+ const config$1 = config.receiveRoutingConfig(routing || {});
22
+ {
23
+ utils.validateReceivedConfig(config$1);
24
+ }
25
+ const pathnames = config$1.pathnames;
26
+
27
+ // This combination requires that the current host is known in order to
28
+ // compute a correct pathname. Since that can only be achieved by reading from
29
+ // headers, this would break static rendering. Therefore, as a workaround we
30
+ // always add a prefix in this case to be on the safe side. The downside is
31
+ // that the user might get redirected again if the middleware detects that the
32
+ // prefix is not needed.
33
+ const forcePrefixSsr = config$1.localePrefix.mode === 'as-needed' && config$1.domains || undefined;
34
+ function Link(_ref, ref) {
35
+ let {
36
+ href,
37
+ locale,
38
+ ...rest
39
+ } = _ref;
40
+ let pathname, params;
41
+ if (typeof href === 'object') {
42
+ pathname = href.pathname;
43
+ // @ts-expect-error -- This is ok
44
+ params = href.params;
45
+ } else {
46
+ pathname = href;
47
+ }
48
+
49
+ // @ts-expect-error -- This is ok
50
+ const isLocalizable = utils$1.isLocalizableHref(href);
51
+ const localePromiseOrValue = getLocale();
52
+ const curLocale = localePromiseOrValue instanceof Promise ? React.use(localePromiseOrValue) : localePromiseOrValue;
53
+ const finalPathname = isLocalizable ? getPathname(
54
+ // @ts-expect-error -- This is ok
55
+ {
56
+ locale: locale || curLocale,
57
+ href: pathnames == null ? pathname : {
58
+ pathname,
59
+ params
60
+ }
61
+ }, locale != null || forcePrefixSsr || undefined) : pathname;
62
+ return /*#__PURE__*/React__default.default.createElement(BaseLink.default, _rollupPluginBabelHelpers.extends({
63
+ ref: ref
64
+ // @ts-expect-error -- Available after the validation
65
+ ,
66
+ defaultLocale: config$1.defaultLocale,
67
+ href: {
68
+ ...(typeof href === 'object' && href),
69
+ // @ts-expect-error -- This is ok
70
+ pathname: finalPathname
71
+ },
72
+ locale: locale,
73
+ localeCookie: config$1.localeCookie
74
+ // Provide the minimal relevant information to the client side in order
75
+ // to potentially remove the prefix in case of the `forcePrefixSsr` case
76
+ ,
77
+ unprefixed: forcePrefixSsr && isLocalizable ? {
78
+ domains: config$1.domains.reduce((acc, domain) => {
79
+ // @ts-expect-error -- This is ok
80
+ acc[domain.domain] = domain.defaultLocale;
81
+ return acc;
82
+ }, {}),
83
+ pathname: getPathname(
84
+ // @ts-expect-error -- This is ok
85
+ {
86
+ locale: curLocale,
87
+ href: pathnames == null ? pathname : {
88
+ pathname,
89
+ params
90
+ }
91
+ }, false)
92
+ } : undefined
93
+ }, rest));
94
+ }
95
+ const LinkWithRef = /*#__PURE__*/React.forwardRef(Link);
96
+ function getPathname(args, /** @private Removed in types returned below */
97
+ _forcePrefix) {
98
+ const {
99
+ href,
100
+ locale
101
+ } = args;
102
+ let pathname;
103
+ if (pathnames == null) {
104
+ if (typeof href === 'object') {
105
+ pathname = href.pathname;
106
+ if (href.query) {
107
+ pathname += utils.serializeSearchParams(href.query);
108
+ }
109
+ } else {
110
+ pathname = href;
111
+ }
112
+ } else {
113
+ pathname = utils.compileLocalizedPathname({
114
+ locale,
115
+ // @ts-expect-error -- This is ok
116
+ ...utils.normalizeNameOrNameWithParams(href),
117
+ // @ts-expect-error -- This is ok
118
+ pathnames: config$1.pathnames
119
+ });
120
+ }
121
+ return utils.applyPathnamePrefix(pathname, locale, config$1,
122
+ // @ts-expect-error -- This is ok
123
+ args.domain, _forcePrefix);
124
+ }
125
+ function getRedirectFn(fn) {
126
+ /** @see https://next-intl-docs.vercel.app/docs/routing/navigation#redirect */
127
+ return function redirectFn(args) {
128
+ for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
129
+ rest[_key - 1] = arguments[_key];
130
+ }
131
+ return fn(
132
+ // @ts-expect-error -- We're forcing the prefix when no domain is provided
133
+ getPathname(args, args.domain ? undefined : forcePrefixSsr), ...rest);
134
+ };
135
+ }
136
+ const redirect = getRedirectFn(navigation.redirect);
137
+ const permanentRedirect = getRedirectFn(navigation.permanentRedirect);
138
+ return {
139
+ config: config$1,
140
+ Link: LinkWithRef,
141
+ redirect,
142
+ permanentRedirect,
143
+ // Remove `_forcePrefix` from public API
144
+ getPathname: getPathname
145
+ };
146
+ }
147
+
148
+ exports.default = createSharedNavigationFns;
@@ -8,6 +8,9 @@ var utils = require('../../shared/utils.js');
8
8
  function createRedirectFn(redirectFn) {
9
9
  return function baseRedirect(params) {
10
10
  const prefix = utils.getLocalePrefix(params.locale, params.localePrefix);
11
+
12
+ // This logic is considered legacy and is replaced by `applyPathnamePrefix`.
13
+ // We keep it this way for now for backwards compatibility.
11
14
  const localizedPathname = params.localePrefix.mode === 'never' || !utils.isLocalizableHref(params.pathname) ? params.pathname : utils.prefixPathname(prefix, params.pathname);
12
15
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
13
16
  args[_key - 1] = arguments[_key];
@@ -2,7 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var constants = require('../../shared/constants.js');
6
5
  var utils = require('./utils.js');
7
6
 
8
7
  /**
@@ -10,9 +9,9 @@ var utils = require('./utils.js');
10
9
  * skip a request to the server due to its router cache.
11
10
  * See https://github.com/amannn/next-intl/issues/786.
12
11
  */
13
- function syncLocaleCookie(pathname, locale, nextLocale) {
12
+ function syncLocaleCookie(localeCookie, pathname, locale, nextLocale) {
14
13
  const isSwitchingLocale = nextLocale !== locale && nextLocale != null;
15
- if (!isSwitchingLocale ||
14
+ if (!localeCookie || !isSwitchingLocale ||
16
15
  // Theoretical case, we always have a pathname in a real app,
17
16
  // only not when running e.g. in a simulated test environment
18
17
  !pathname) {
@@ -20,11 +19,33 @@ function syncLocaleCookie(pathname, locale, nextLocale) {
20
19
  }
21
20
  const basePath = utils.getBasePath(pathname);
22
21
  const hasBasePath = basePath !== '';
23
- const path = hasBasePath ? basePath : '/';
22
+ const defaultPath = hasBasePath ? basePath : '/';
23
+ const {
24
+ name,
25
+ ...rest
26
+ } = localeCookie;
27
+ if (!rest.path) {
28
+ rest.path = defaultPath;
29
+ }
30
+ let localeCookieString = "".concat(name, "=").concat(nextLocale, ";");
31
+ for (const [key, value] of Object.entries(rest)) {
32
+ // Map object properties to cookie properties.
33
+ // Interestingly, `maxAge` corresponds to `max-age`,
34
+ // while `sameSite` corresponds to `SameSite`.
35
+ // Also, keys are case-insensitive.
36
+ const targetKey = key === 'maxAge' ? 'max-age' : key;
37
+ localeCookieString += "".concat(targetKey);
38
+ if (typeof value !== 'boolean') {
39
+ localeCookieString += '=' + value;
40
+ }
41
+
42
+ // A trailing ";" is allowed by browsers
43
+ localeCookieString += ';';
44
+ }
24
45
 
25
46
  // Note that writing to `document.cookie` doesn't overwrite all
26
47
  // cookies, but only the ones referenced via the name here.
27
- document.cookie = "".concat(constants.COOKIE_LOCALE_NAME, "=").concat(nextLocale, "; path=").concat(path, "; max-age=").concat(constants.COOKIE_MAX_AGE, "; sameSite=").concat(constants.COOKIE_SAME_SITE);
48
+ document.cookie = localeCookieString;
28
49
  }
29
50
 
30
51
  exports.default = syncLocaleCookie;
@@ -7,8 +7,11 @@ var utils = require('../../shared/utils.js');
7
7
  // Minor false positive: A route that has both optional and
8
8
  // required params will allow optional params.
9
9
 
10
+ // For `Link`
11
+
12
+ // For `getPathname` (hence also its consumers: `redirect`, `useRouter`, …)
13
+
10
14
  function normalizeNameOrNameWithParams(href) {
11
- // @ts-expect-error -- `extends string` in the generic unfortunately weakens the type
12
15
  return typeof href === 'string' ? {
13
16
  pathname: href
14
17
  } : href;
@@ -40,6 +43,7 @@ function compileLocalizedPathname(_ref) {
40
43
  function getNamedPath(value) {
41
44
  let namedPath = pathnames[value];
42
45
  if (!namedPath) {
46
+ // Unknown pathnames
43
47
  namedPath = value;
44
48
  }
45
49
  return namedPath;
@@ -118,9 +122,44 @@ function getBasePath(pathname) {
118
122
  return windowPathname.replace(pathname, '');
119
123
  }
120
124
  }
125
+ function applyPathnamePrefix(pathname, locale, routing, domain, force) {
126
+ const {
127
+ mode
128
+ } = routing.localePrefix;
129
+ let shouldPrefix;
130
+ if (force !== undefined) {
131
+ shouldPrefix = force;
132
+ } else if (utils.isLocalizableHref(pathname)) {
133
+ if (mode === 'always') {
134
+ shouldPrefix = true;
135
+ } else if (mode === 'as-needed') {
136
+ let defaultLocale = routing.defaultLocale;
137
+ if (routing.domains) {
138
+ const domainConfig = routing.domains.find(cur => cur.domain === domain);
139
+ if (domainConfig) {
140
+ defaultLocale = domainConfig.defaultLocale;
141
+ } else {
142
+ if (!domain) {
143
+ console.error("You're using a routing configuration with `localePrefix: 'as-needed'` in combination with `domains`. In order to compute a correct pathname, you need to provide a `domain` parameter.\n\nSee: https://next-intl-docs.vercel.app/docs/routing#domains-localeprefix-asneeded");
144
+ }
145
+ }
146
+ }
147
+ shouldPrefix = defaultLocale !== locale;
148
+ }
149
+ }
150
+ return shouldPrefix ? utils.prefixPathname(utils.getLocalePrefix(locale, routing.localePrefix), pathname) : pathname;
151
+ }
152
+ function validateReceivedConfig(config) {
153
+ var _config$localePrefix;
154
+ if (((_config$localePrefix = config.localePrefix) === null || _config$localePrefix === void 0 ? void 0 : _config$localePrefix.mode) === 'as-needed' && !('defaultLocale' in config)) {
155
+ throw new Error("`localePrefix: 'as-needed' requires a `defaultLocale`.");
156
+ }
157
+ }
121
158
 
159
+ exports.applyPathnamePrefix = applyPathnamePrefix;
122
160
  exports.compileLocalizedPathname = compileLocalizedPathname;
123
161
  exports.getBasePath = getBasePath;
124
162
  exports.getRoute = getRoute;
125
163
  exports.normalizeNameOrNameWithParams = normalizeNameOrNameWithParams;
126
164
  exports.serializeSearchParams = serializeSearchParams;
165
+ exports.validateReceivedConfig = validateReceivedConfig;
@@ -4,8 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var createSharedPathnamesNavigation = require('./navigation/react-client/createSharedPathnamesNavigation.js');
6
6
  var createLocalizedPathnamesNavigation = require('./navigation/react-client/createLocalizedPathnamesNavigation.js');
7
+ var createNavigation = require('./navigation/react-client/createNavigation.js');
7
8
 
8
9
 
9
10
 
10
11
  exports.createSharedPathnamesNavigation = createSharedPathnamesNavigation.default;
11
12
  exports.createLocalizedPathnamesNavigation = createLocalizedPathnamesNavigation.default;
13
+ exports.createNavigation = createNavigation.default;
@@ -4,8 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var createSharedPathnamesNavigation = require('./navigation/react-server/createSharedPathnamesNavigation.js');
6
6
  var createLocalizedPathnamesNavigation = require('./navigation/react-server/createLocalizedPathnamesNavigation.js');
7
+ var createNavigation = require('./navigation/react-server/createNavigation.js');
7
8
 
8
9
 
9
10
 
10
11
  exports.createSharedPathnamesNavigation = createSharedPathnamesNavigation.default;
11
12
  exports.createLocalizedPathnamesNavigation = createLocalizedPathnamesNavigation.default;
13
+ exports.createNavigation = createNavigation.default;
@@ -14,8 +14,6 @@ var useIntl = require('use-intl');
14
14
  * supported in all Next.js versions that are supported.
15
15
  */
16
16
 
17
-
18
- // eslint-disable-next-line @typescript-eslint/ban-types
19
17
  function callHook(name, hook) {
20
18
  return function () {
21
19
  try {
@@ -3,16 +3,33 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  function receiveRoutingConfig(input) {
6
+ var _input$localeDetectio, _input$alternateLinks;
6
7
  return {
7
8
  ...input,
8
- localePrefix: receiveLocalePrefixConfig(input.localePrefix)
9
+ localePrefix: receiveLocalePrefixConfig(input === null || input === void 0 ? void 0 : input.localePrefix),
10
+ localeCookie: receiveLocaleCookie(input.localeCookie),
11
+ localeDetection: (_input$localeDetectio = input.localeDetection) !== null && _input$localeDetectio !== void 0 ? _input$localeDetectio : true,
12
+ alternateLinks: (_input$alternateLinks = input.alternateLinks) !== null && _input$alternateLinks !== void 0 ? _input$alternateLinks : true
9
13
  };
10
14
  }
15
+ function receiveLocaleCookie(localeCookie) {
16
+ return (localeCookie !== null && localeCookie !== void 0 ? localeCookie : true) ? {
17
+ name: 'NEXT_LOCALE',
18
+ maxAge: 31536000,
19
+ // 1 year
20
+ sameSite: 'lax',
21
+ ...(typeof localeCookie === 'object' && localeCookie)
22
+
23
+ // `path` needs to be provided based on a detected base path
24
+ // that depends on the environment when setting a cookie
25
+ } : false;
26
+ }
11
27
  function receiveLocalePrefixConfig(localePrefix) {
12
28
  return typeof localePrefix === 'object' ? localePrefix : {
13
29
  mode: localePrefix || 'always'
14
30
  };
15
31
  }
16
32
 
33
+ exports.receiveLocaleCookie = receiveLocaleCookie;
17
34
  exports.receiveLocalePrefixConfig = receiveLocalePrefixConfig;
18
35
  exports.receiveRoutingConfig = receiveRoutingConfig;
@@ -3,47 +3,37 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var headers = require('next/headers');
6
- var navigation = require('next/navigation');
7
6
  var React = require('react');
8
7
  var constants = require('../../shared/constants.js');
8
+ var RequestLocaleCache = require('./RequestLocaleCache.js');
9
9
 
10
- function getLocaleFromHeaderImpl() {
10
+ async function getHeadersImpl() {
11
+ const promiseOrValue = headers.headers();
12
+
13
+ // Compatibility with Next.js <15
14
+ return promiseOrValue instanceof Promise ? await promiseOrValue : promiseOrValue;
15
+ }
16
+ const getHeaders = React.cache(getHeadersImpl);
17
+ async function getLocaleFromHeaderImpl() {
11
18
  let locale;
12
19
  try {
13
- locale = headers.headers().get(constants.HEADER_LOCALE_NAME);
20
+ locale = (await getHeaders()).get(constants.HEADER_LOCALE_NAME) || undefined;
14
21
  } catch (error) {
15
22
  if (error instanceof Error && error.digest === 'DYNAMIC_SERVER_USAGE') {
16
- throw new Error('Usage of next-intl APIs in Server Components currently opts into dynamic rendering. This limitation will eventually be lifted, but as a stopgap solution, you can use the `unstable_setRequestLocale` API to enable static rendering, see https://next-intl-docs.vercel.app/docs/getting-started/app-router/with-i18n-routing#static-rendering', {
23
+ const wrappedError = new Error('Usage of next-intl APIs in Server Components currently opts into dynamic rendering. This limitation will eventually be lifted, but as a stopgap solution, you can use the `unstable_setRequestLocale` API to enable static rendering, see https://next-intl-docs.vercel.app/docs/getting-started/app-router/with-i18n-routing#static-rendering', {
17
24
  cause: error
18
25
  });
26
+ wrappedError.digest = error.digest;
27
+ throw wrappedError;
19
28
  } else {
20
29
  throw error;
21
30
  }
22
31
  }
23
- if (!locale) {
24
- {
25
- console.error("\nUnable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale. The `notFound()` function will be called as a result.\n");
26
- }
27
- navigation.notFound();
28
- }
29
32
  return locale;
30
33
  }
31
34
  const getLocaleFromHeader = React.cache(getLocaleFromHeaderImpl);
32
-
33
- // Workaround until `createServerContext` is available
34
- function getCacheImpl() {
35
- const value = {
36
- locale: undefined
37
- };
38
- return value;
39
- }
40
- const getCache = React.cache(getCacheImpl);
41
- function setRequestLocale(locale) {
42
- getCache().locale = locale;
43
- }
44
- function getRequestLocale() {
45
- return getCache().locale || getLocaleFromHeader();
35
+ async function getRequestLocale() {
36
+ return RequestLocaleCache.getCachedRequestLocale() || (await getLocaleFromHeader());
46
37
  }
47
38
 
48
39
  exports.getRequestLocale = getRequestLocale;
49
- exports.setRequestLocale = setRequestLocale;
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var React = require('react');
6
+
7
+ // See https://github.com/vercel/next.js/discussions/58862
8
+ function getCacheImpl() {
9
+ const value = {
10
+ locale: undefined
11
+ };
12
+ return value;
13
+ }
14
+ const getCache = React.cache(getCacheImpl);
15
+ function getCachedRequestLocale() {
16
+ return getCache().locale;
17
+ }
18
+ function setCachedRequestLocale(locale) {
19
+ getCache().locale = locale;
20
+ }
21
+
22
+ exports.getCachedRequestLocale = getCachedRequestLocale;
23
+ exports.setCachedRequestLocale = setCachedRequestLocale;
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var headers = require('next/headers');
6
+ var navigation = require('next/navigation');
7
+ var React = require('react');
8
+ var constants = require('../../shared/constants.js');
9
+ var RequestLocaleCache = require('./RequestLocaleCache.js');
10
+
11
+ // This was originally built for Next.js <14, where `headers()` was not async.
12
+ // With https://github.com/vercel/next.js/pull/68812, the API became async.
13
+ // This file can be removed once we remove the legacy navigation APIs.
14
+ function getHeaders() {
15
+ return headers.headers();
16
+ }
17
+ function getLocaleFromHeaderImpl() {
18
+ let locale;
19
+ try {
20
+ locale = getHeaders().get(constants.HEADER_LOCALE_NAME);
21
+ } catch (error) {
22
+ if (error instanceof Error && error.digest === 'DYNAMIC_SERVER_USAGE') {
23
+ throw new Error('Usage of next-intl APIs in Server Components currently opts into dynamic rendering. This limitation will eventually be lifted, but as a stopgap solution, you can use the `unstable_setRequestLocale` API to enable static rendering, see https://next-intl-docs.vercel.app/docs/getting-started/app-router/with-i18n-routing#static-rendering', {
24
+ cause: error
25
+ });
26
+ } else {
27
+ throw error;
28
+ }
29
+ }
30
+ if (!locale) {
31
+ {
32
+ console.error("\nUnable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale. The `notFound()` function will be called as a result.\n");
33
+ }
34
+ navigation.notFound();
35
+ }
36
+ return locale;
37
+ }
38
+ const getLocaleFromHeader = React.cache(getLocaleFromHeaderImpl);
39
+ function getRequestLocale() {
40
+ return RequestLocaleCache.getCachedRequestLocale() || getLocaleFromHeader();
41
+ }
42
+
43
+ exports.getRequestLocale = getRequestLocale;
@@ -2,9 +2,11 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var navigation = require('next/navigation');
5
6
  var React = require('react');
6
7
  var core = require('use-intl/core');
7
8
  var RequestLocale = require('./RequestLocale.js');
9
+ var RequestLocaleLegacy = require('./RequestLocaleLegacy.js');
8
10
  var getRuntimeConfig = require('next-intl/config');
9
11
 
10
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -27,35 +29,31 @@ async function receiveRuntimeConfigImpl(getConfig, localeOverride) {
27
29
  if (typeof getConfig !== 'function') {
28
30
  throw new Error("Invalid i18n request configuration detected.\n\nPlease verify that:\n1. In case you've specified a custom location in your Next.js config, make sure that the path is correct.\n2. You have a default export in your i18n request configuration file.\n\nSee also: https://next-intl-docs.vercel.app/docs/usage/configuration#i18n-request\n");
29
31
  }
30
- let hasReadLocale = false;
31
-
32
- // In case the consumer doesn't read `params.locale` and instead provides the
33
- // `locale` (either in a single-language workflow or because the locale is
34
- // read from the user settings), don't attempt to read the request locale.
35
32
  const params = {
33
+ // In case the consumer doesn't read `params.locale` and instead provides the
34
+ // `locale` (either in a single-language workflow or because the locale is
35
+ // read from the user settings), don't attempt to read the request locale.
36
36
  get locale() {
37
- hasReadLocale = true;
38
- return localeOverride || RequestLocale.getRequestLocale();
37
+ return localeOverride || RequestLocaleLegacy.getRequestLocale();
38
+ },
39
+ get requestLocale() {
40
+ return localeOverride ? Promise.resolve(localeOverride) : RequestLocale.getRequestLocale();
39
41
  }
40
42
  };
41
43
  let result = getConfig(params);
42
44
  if (result instanceof Promise) {
43
45
  result = await result;
44
46
  }
45
- {
46
- if (hasReadLocale) {
47
- if (result.locale) {
48
- console.error("\nYou've read the `locale` param that was passed to `getRequestConfig` but have also returned one from the function. This is likely an error, please ensure that you're consistently using a setup with or without i18n routing: https://next-intl-docs.vercel.app/docs/getting-started/app-router\n");
49
- }
50
- } else {
51
- if (!result.locale) {
52
- console.error("\nYou haven't read the `locale` param that was passed to `getRequestConfig` and also haven't returned one from the function. This is likely an error, please ensure that you're consistently using a setup with or without i18n routing: https://next-intl-docs.vercel.app/docs/getting-started/app-router\n");
53
- }
47
+ const locale = result.locale || (await params.requestLocale);
48
+ if (!locale) {
49
+ {
50
+ console.error("\nUnable to find `next-intl` locale because the middleware didn't run on this request and no `locale` was returned in `getRequestConfig`. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale. The `notFound()` function will be called as a result.\n");
54
51
  }
52
+ navigation.notFound();
55
53
  }
56
54
  return {
57
55
  ...result,
58
- locale: result.locale || params.locale,
56
+ locale,
59
57
  now: result.now || getDefaultNow(),
60
58
  timeZone: result.timeZone || getDefaultTimeZone()
61
59
  };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  /**
6
- * Should be called in `i18n.ts` to create the configuration for the current request.
6
+ * Should be called in `i18n/request.ts` to create the configuration for the current request.
7
7
  */
8
8
  function getRequestConfig(createRequestConfig) {
9
9
  return createRequestConfig;
@@ -9,7 +9,7 @@ var getNow = require('./server/react-server/getNow.js');
9
9
  var getTimeZone = require('./server/react-server/getTimeZone.js');
10
10
  var getTranslations = require('./server/react-server/getTranslations.js');
11
11
  var getLocale = require('./server/react-server/getLocale.js');
12
- var RequestLocale = require('./server/react-server/RequestLocale.js');
12
+ var RequestLocaleCache = require('./server/react-server/RequestLocaleCache.js');
13
13
 
14
14
 
15
15
 
@@ -20,4 +20,4 @@ exports.getNow = getNow.default;
20
20
  exports.getTimeZone = getTimeZone.default;
21
21
  exports.getTranslations = getTranslations.default;
22
22
  exports.getLocale = getLocale.default;
23
- exports.unstable_setRequestLocale = RequestLocale.setRequestLocale;
23
+ exports.unstable_setRequestLocale = RequestLocaleCache.setCachedRequestLocale;
@@ -2,20 +2,11 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- // Reuse the legacy cookie name
6
- // https://nextjs.org/docs/advanced-features/i18n-routing#leveraging-the-next_locale-cookie
7
- const COOKIE_LOCALE_NAME = 'NEXT_LOCALE';
8
- const COOKIE_MAX_AGE = 31536000; // 1 year
9
- const COOKIE_SAME_SITE = 'lax';
10
-
11
5
  // Should take precedence over the cookie
12
6
  const HEADER_LOCALE_NAME = 'X-NEXT-INTL-LOCALE';
13
7
 
14
8
  // In a URL like "/en-US/about", the locale segment is "en-US"
15
9
  const LOCALE_SEGMENT_NAME = 'locale';
16
10
 
17
- exports.COOKIE_LOCALE_NAME = COOKIE_LOCALE_NAME;
18
- exports.COOKIE_MAX_AGE = COOKIE_MAX_AGE;
19
- exports.COOKIE_SAME_SITE = COOKIE_SAME_SITE;
20
11
  exports.HEADER_LOCALE_NAME = HEADER_LOCALE_NAME;
21
12
  exports.LOCALE_SEGMENT_NAME = LOCALE_SEGMENT_NAME;