@depup/next-intl 4.8.3-depup.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 (296) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +33 -0
  3. package/changes.json +18 -0
  4. package/config.d.ts +4 -0
  5. package/dist/cjs/development/ExtractorCodec-D9Tw618d.cjs +7 -0
  6. package/dist/cjs/development/JSONCodec-rhejs716.cjs +50 -0
  7. package/dist/cjs/development/POCodec-Cv3VdXQG.cjs +105 -0
  8. package/dist/cjs/development/plugin-YzBhQjAo.cjs +1457 -0
  9. package/dist/cjs/development/plugin.cjs +13 -0
  10. package/dist/esm/development/config.js +5 -0
  11. package/dist/esm/development/extractor/ExtractionCompiler.js +38 -0
  12. package/dist/esm/development/extractor/catalog/CatalogLocales.js +84 -0
  13. package/dist/esm/development/extractor/catalog/CatalogManager.js +370 -0
  14. package/dist/esm/development/extractor/catalog/CatalogPersister.js +63 -0
  15. package/dist/esm/development/extractor/catalog/SaveScheduler.js +85 -0
  16. package/dist/esm/development/extractor/catalogLoader.js +96 -0
  17. package/dist/esm/development/extractor/extractMessages.js +15 -0
  18. package/dist/esm/development/extractor/extractionLoader.js +26 -0
  19. package/dist/esm/development/extractor/extractor/LRUCache.js +30 -0
  20. package/dist/esm/development/extractor/extractor/MessageExtractor.js +66 -0
  21. package/dist/esm/development/extractor/format/ExtractorCodec.js +5 -0
  22. package/dist/esm/development/extractor/format/codecs/JSONCodec.js +42 -0
  23. package/dist/esm/development/extractor/format/codecs/POCodec.js +93 -0
  24. package/dist/esm/development/extractor/format/index.js +44 -0
  25. package/dist/esm/development/extractor/source/SourceFileFilter.js +29 -0
  26. package/dist/esm/development/extractor/source/SourceFileScanner.js +31 -0
  27. package/dist/esm/development/extractor/source/SourceFileWatcher.js +132 -0
  28. package/dist/esm/development/extractor/utils.js +46 -0
  29. package/dist/esm/development/extractor.js +2 -0
  30. package/dist/esm/development/index.react-client.js +4 -0
  31. package/dist/esm/development/index.react-server.js +9 -0
  32. package/dist/esm/development/middleware/getAlternateLinksHeaderValue.js +91 -0
  33. package/dist/esm/development/middleware/middleware.js +168 -0
  34. package/dist/esm/development/middleware/resolveLocale.js +129 -0
  35. package/dist/esm/development/middleware/syncCookie.js +27 -0
  36. package/dist/esm/development/middleware/utils.js +194 -0
  37. package/dist/esm/development/middleware.js +1 -0
  38. package/dist/esm/development/navigation/react-client/createNavigation.js +80 -0
  39. package/dist/esm/development/navigation/react-client/useBasePathname.js +36 -0
  40. package/dist/esm/development/navigation/react-server/createNavigation.js +22 -0
  41. package/dist/esm/development/navigation/react-server/getServerLocale.js +12 -0
  42. package/dist/esm/development/navigation/shared/BaseLink.js +51 -0
  43. package/dist/esm/development/navigation/shared/createSharedNavigationFns.js +105 -0
  44. package/dist/esm/development/navigation/shared/syncLocaleCookie.js +47 -0
  45. package/dist/esm/development/navigation/shared/utils.js +165 -0
  46. package/dist/esm/development/navigation.react-client.js +1 -0
  47. package/dist/esm/development/navigation.react-server.js +1 -0
  48. package/dist/esm/development/plugin/config.js +10 -0
  49. package/dist/esm/development/plugin/createNextIntlPlugin.js +26 -0
  50. package/dist/esm/development/plugin/declaration/createMessagesDeclaration.js +70 -0
  51. package/dist/esm/development/plugin/extractor/initExtractionCompiler.js +59 -0
  52. package/dist/esm/development/plugin/getNextConfig.js +267 -0
  53. package/dist/esm/development/plugin/nextFlags.js +32 -0
  54. package/dist/esm/development/plugin/utils.js +26 -0
  55. package/dist/esm/development/plugin/watchFile.js +21 -0
  56. package/dist/esm/development/plugin.js +1 -0
  57. package/dist/esm/development/react-client/index.js +34 -0
  58. package/dist/esm/development/react-server/NextIntlClientProviderServer.js +34 -0
  59. package/dist/esm/development/react-server/useConfig.js +21 -0
  60. package/dist/esm/development/react-server/useExtracted.js +9 -0
  61. package/dist/esm/development/react-server/useFormatter.js +9 -0
  62. package/dist/esm/development/react-server/useLocale.js +8 -0
  63. package/dist/esm/development/react-server/useMessages.js +9 -0
  64. package/dist/esm/development/react-server/useNow.js +12 -0
  65. package/dist/esm/development/react-server/useTimeZone.js +8 -0
  66. package/dist/esm/development/react-server/useTranslations.js +9 -0
  67. package/dist/esm/development/routing/config.js +26 -0
  68. package/dist/esm/development/routing/defineRouting.js +25 -0
  69. package/dist/esm/development/routing.js +1 -0
  70. package/dist/esm/development/server/react-client/index.js +32 -0
  71. package/dist/esm/development/server/react-server/RequestLocale.js +36 -0
  72. package/dist/esm/development/server/react-server/RequestLocaleCache.js +18 -0
  73. package/dist/esm/development/server/react-server/createRequestConfig.js +2 -0
  74. package/dist/esm/development/server/react-server/getConfig.js +59 -0
  75. package/dist/esm/development/server/react-server/getConfigNow.js +10 -0
  76. package/dist/esm/development/server/react-server/getDefaultNow.js +9 -0
  77. package/dist/esm/development/server/react-server/getExtracted.js +24 -0
  78. package/dist/esm/development/server/react-server/getFormats.js +10 -0
  79. package/dist/esm/development/server/react-server/getFormatter.js +21 -0
  80. package/dist/esm/development/server/react-server/getLocale.js +10 -0
  81. package/dist/esm/development/server/react-server/getMessages.js +19 -0
  82. package/dist/esm/development/server/react-server/getNow.js +8 -0
  83. package/dist/esm/development/server/react-server/getRequestConfig.js +8 -0
  84. package/dist/esm/development/server/react-server/getServerExtractor.js +38 -0
  85. package/dist/esm/development/server/react-server/getServerFormatter.js +17 -0
  86. package/dist/esm/development/server/react-server/getServerTranslator.js +12 -0
  87. package/dist/esm/development/server/react-server/getTimeZone.js +13 -0
  88. package/dist/esm/development/server/react-server/getTranslations.js +28 -0
  89. package/dist/esm/development/server/react-server/validateLocale.js +12 -0
  90. package/dist/esm/development/server.react-client.js +1 -0
  91. package/dist/esm/development/server.react-server.js +9 -0
  92. package/dist/esm/development/shared/NextIntlClientProvider.js +18 -0
  93. package/dist/esm/development/shared/constants.js +4 -0
  94. package/dist/esm/development/shared/use.js +13 -0
  95. package/dist/esm/development/shared/utils.js +140 -0
  96. package/dist/esm/production/config.js +1 -0
  97. package/dist/esm/production/extractor/ExtractionCompiler.js +1 -0
  98. package/dist/esm/production/extractor/catalog/CatalogLocales.js +1 -0
  99. package/dist/esm/production/extractor/catalog/CatalogManager.js +1 -0
  100. package/dist/esm/production/extractor/catalog/CatalogPersister.js +1 -0
  101. package/dist/esm/production/extractor/catalog/SaveScheduler.js +1 -0
  102. package/dist/esm/production/extractor/catalogLoader.js +1 -0
  103. package/dist/esm/production/extractor/extractMessages.js +1 -0
  104. package/dist/esm/production/extractor/extractionLoader.js +1 -0
  105. package/dist/esm/production/extractor/extractor/LRUCache.js +1 -0
  106. package/dist/esm/production/extractor/extractor/MessageExtractor.js +1 -0
  107. package/dist/esm/production/extractor/format/ExtractorCodec.js +1 -0
  108. package/dist/esm/production/extractor/format/codecs/JSONCodec.js +1 -0
  109. package/dist/esm/production/extractor/format/codecs/POCodec.js +1 -0
  110. package/dist/esm/production/extractor/format/index.js +1 -0
  111. package/dist/esm/production/extractor/source/SourceFileFilter.js +1 -0
  112. package/dist/esm/production/extractor/source/SourceFileScanner.js +1 -0
  113. package/dist/esm/production/extractor/source/SourceFileWatcher.js +1 -0
  114. package/dist/esm/production/extractor/utils.js +1 -0
  115. package/dist/esm/production/extractor.js +1 -0
  116. package/dist/esm/production/index.react-client.js +1 -0
  117. package/dist/esm/production/index.react-server.js +1 -0
  118. package/dist/esm/production/middleware/getAlternateLinksHeaderValue.js +1 -0
  119. package/dist/esm/production/middleware/middleware.js +1 -0
  120. package/dist/esm/production/middleware/resolveLocale.js +1 -0
  121. package/dist/esm/production/middleware/syncCookie.js +1 -0
  122. package/dist/esm/production/middleware/utils.js +1 -0
  123. package/dist/esm/production/middleware.js +1 -0
  124. package/dist/esm/production/navigation/react-client/createNavigation.js +1 -0
  125. package/dist/esm/production/navigation/react-client/useBasePathname.js +1 -0
  126. package/dist/esm/production/navigation/react-server/createNavigation.js +1 -0
  127. package/dist/esm/production/navigation/react-server/getServerLocale.js +1 -0
  128. package/dist/esm/production/navigation/shared/BaseLink.js +2 -0
  129. package/dist/esm/production/navigation/shared/createSharedNavigationFns.js +1 -0
  130. package/dist/esm/production/navigation/shared/syncLocaleCookie.js +1 -0
  131. package/dist/esm/production/navigation/shared/utils.js +1 -0
  132. package/dist/esm/production/navigation.react-client.js +1 -0
  133. package/dist/esm/production/navigation.react-server.js +1 -0
  134. package/dist/esm/production/plugin/config.js +1 -0
  135. package/dist/esm/production/plugin/createNextIntlPlugin.js +1 -0
  136. package/dist/esm/production/plugin/declaration/createMessagesDeclaration.js +1 -0
  137. package/dist/esm/production/plugin/extractor/initExtractionCompiler.js +1 -0
  138. package/dist/esm/production/plugin/getNextConfig.js +1 -0
  139. package/dist/esm/production/plugin/nextFlags.js +1 -0
  140. package/dist/esm/production/plugin/utils.js +1 -0
  141. package/dist/esm/production/plugin/watchFile.js +1 -0
  142. package/dist/esm/production/plugin.js +1 -0
  143. package/dist/esm/production/react-client/index.js +1 -0
  144. package/dist/esm/production/react-server/NextIntlClientProviderServer.js +1 -0
  145. package/dist/esm/production/react-server/useConfig.js +1 -0
  146. package/dist/esm/production/react-server/useExtracted.js +1 -0
  147. package/dist/esm/production/react-server/useFormatter.js +1 -0
  148. package/dist/esm/production/react-server/useLocale.js +1 -0
  149. package/dist/esm/production/react-server/useMessages.js +1 -0
  150. package/dist/esm/production/react-server/useNow.js +1 -0
  151. package/dist/esm/production/react-server/useTimeZone.js +1 -0
  152. package/dist/esm/production/react-server/useTranslations.js +1 -0
  153. package/dist/esm/production/routing/config.js +1 -0
  154. package/dist/esm/production/routing/defineRouting.js +1 -0
  155. package/dist/esm/production/routing.js +1 -0
  156. package/dist/esm/production/server/react-client/index.js +1 -0
  157. package/dist/esm/production/server/react-server/RequestLocale.js +1 -0
  158. package/dist/esm/production/server/react-server/RequestLocaleCache.js +1 -0
  159. package/dist/esm/production/server/react-server/createRequestConfig.js +1 -0
  160. package/dist/esm/production/server/react-server/getConfig.js +1 -0
  161. package/dist/esm/production/server/react-server/getConfigNow.js +1 -0
  162. package/dist/esm/production/server/react-server/getDefaultNow.js +1 -0
  163. package/dist/esm/production/server/react-server/getExtracted.js +1 -0
  164. package/dist/esm/production/server/react-server/getFormats.js +1 -0
  165. package/dist/esm/production/server/react-server/getFormatter.js +1 -0
  166. package/dist/esm/production/server/react-server/getLocale.js +1 -0
  167. package/dist/esm/production/server/react-server/getMessages.js +1 -0
  168. package/dist/esm/production/server/react-server/getNow.js +1 -0
  169. package/dist/esm/production/server/react-server/getRequestConfig.js +1 -0
  170. package/dist/esm/production/server/react-server/getServerExtractor.js +1 -0
  171. package/dist/esm/production/server/react-server/getServerFormatter.js +1 -0
  172. package/dist/esm/production/server/react-server/getServerTranslator.js +1 -0
  173. package/dist/esm/production/server/react-server/getTimeZone.js +1 -0
  174. package/dist/esm/production/server/react-server/getTranslations.js +1 -0
  175. package/dist/esm/production/server.react-client.js +1 -0
  176. package/dist/esm/production/server.react-server.js +1 -0
  177. package/dist/esm/production/shared/NextIntlClientProvider.js +2 -0
  178. package/dist/esm/production/shared/constants.js +1 -0
  179. package/dist/esm/production/shared/use.js +1 -0
  180. package/dist/esm/production/shared/utils.js +1 -0
  181. package/dist/types/config.d.ts +1 -0
  182. package/dist/types/extractor/ExtractionCompiler.d.ts +15 -0
  183. package/dist/types/extractor/catalog/CatalogLocales.d.ts +29 -0
  184. package/dist/types/extractor/catalog/CatalogManager.d.ts +59 -0
  185. package/dist/types/extractor/catalog/CatalogPersister.d.ts +20 -0
  186. package/dist/types/extractor/catalog/SaveScheduler.d.ts +18 -0
  187. package/dist/types/extractor/extractMessages.d.ts +2 -0
  188. package/dist/types/extractor/extractor/KeyGenerator.d.ts +3 -0
  189. package/dist/types/extractor/extractor/LRUCache.d.ts +7 -0
  190. package/dist/types/extractor/extractor/MessageExtractor.bench.d.ts +1 -0
  191. package/dist/types/extractor/extractor/MessageExtractor.d.ts +21 -0
  192. package/dist/types/extractor/format/ExtractorCodec.d.ts +33 -0
  193. package/dist/types/extractor/format/codecs/JSONCodec.d.ts +2 -0
  194. package/dist/types/extractor/format/codecs/POCodec.d.ts +2 -0
  195. package/dist/types/extractor/format/codecs/fixtures/JSONCodecStructured.d.ts +2 -0
  196. package/dist/types/extractor/format/codecs/fixtures/POCodecSourceMessageKey.d.ts +2 -0
  197. package/dist/types/extractor/format/index.d.ts +15 -0
  198. package/dist/types/extractor/format/types.d.ts +8 -0
  199. package/dist/types/extractor/index.d.ts +2 -0
  200. package/dist/types/extractor/source/SourceFileFilter.d.ts +8 -0
  201. package/dist/types/extractor/source/SourceFileScanner.d.ts +4 -0
  202. package/dist/types/extractor/source/SourceFileWatcher.d.ts +15 -0
  203. package/dist/types/extractor/types.d.ts +28 -0
  204. package/dist/types/extractor/utils.d.ts +7 -0
  205. package/dist/types/extractor.d.ts +1 -0
  206. package/dist/types/index.react-client.d.ts +8 -0
  207. package/dist/types/index.react-server.d.ts +1 -0
  208. package/dist/types/middleware/getAlternateLinksHeaderValue.d.ts +13 -0
  209. package/dist/types/middleware/index.d.ts +4 -0
  210. package/dist/types/middleware/middleware.d.ts +4 -0
  211. package/dist/types/middleware/resolveLocale.d.ts +9 -0
  212. package/dist/types/middleware/syncCookie.d.ts +7 -0
  213. package/dist/types/middleware/utils.d.ts +26 -0
  214. package/dist/types/middleware.d.ts +1 -0
  215. package/dist/types/navigation/react-client/createNavigation.d.ts +464 -0
  216. package/dist/types/navigation/react-client/index.d.ts +2 -0
  217. package/dist/types/navigation/react-client/useBasePathname.d.ts +5 -0
  218. package/dist/types/navigation/react-server/createNavigation.d.ts +384 -0
  219. package/dist/types/navigation/react-server/getServerLocale.d.ts +5 -0
  220. package/dist/types/navigation/react-server/index.d.ts +2 -0
  221. package/dist/types/navigation/shared/BaseLink.d.ts +11 -0
  222. package/dist/types/navigation/shared/StrictParams.d.ts +8 -0
  223. package/dist/types/navigation/shared/createSharedNavigationFns.d.ts +370 -0
  224. package/dist/types/navigation/shared/syncLocaleCookie.d.ts +8 -0
  225. package/dist/types/navigation/shared/utils.d.ts +53 -0
  226. package/dist/types/navigation.react-client.d.ts +1 -0
  227. package/dist/types/navigation.react-server.d.ts +1 -0
  228. package/dist/types/plugin/catalog/catalogLoader.d.ts +10 -0
  229. package/dist/types/plugin/config.d.ts +3 -0
  230. package/dist/types/plugin/createNextIntlPlugin.d.ts +3 -0
  231. package/dist/types/plugin/declaration/createMessagesDeclaration.d.ts +1 -0
  232. package/dist/types/plugin/declaration/index.d.ts +1 -0
  233. package/dist/types/plugin/extractor/extractionLoader.d.ts +3 -0
  234. package/dist/types/plugin/extractor/initExtractionCompiler.d.ts +2 -0
  235. package/dist/types/plugin/getNextConfig.d.ts +3 -0
  236. package/dist/types/plugin/index.d.ts +1 -0
  237. package/dist/types/plugin/nextFlags.d.ts +2 -0
  238. package/dist/types/plugin/types.d.ts +29 -0
  239. package/dist/types/plugin/utils.d.ts +8 -0
  240. package/dist/types/plugin/watchFile.d.ts +6 -0
  241. package/dist/types/plugin.d.ts +1 -0
  242. package/dist/types/react-client/index.d.ts +16 -0
  243. package/dist/types/react-server/NextIntlClientProviderServer.d.ts +5 -0
  244. package/dist/types/react-server/index.d.ts +16 -0
  245. package/dist/types/react-server/testUtils.d.ts +2 -0
  246. package/dist/types/react-server/useConfig.d.ts +2 -0
  247. package/dist/types/react-server/useExtracted.d.ts +2 -0
  248. package/dist/types/react-server/useFormatter.d.ts +2 -0
  249. package/dist/types/react-server/useLocale.d.ts +2 -0
  250. package/dist/types/react-server/useMessages.d.ts +2 -0
  251. package/dist/types/react-server/useNow.d.ts +2 -0
  252. package/dist/types/react-server/useTimeZone.d.ts +2 -0
  253. package/dist/types/react-server/useTranslations.d.ts +2 -0
  254. package/dist/types/routing/config.d.ts +73 -0
  255. package/dist/types/routing/defineRouting.d.ts +3 -0
  256. package/dist/types/routing/index.d.ts +3 -0
  257. package/dist/types/routing/types.d.ts +24 -0
  258. package/dist/types/routing.d.ts +1 -0
  259. package/dist/types/server/react-client/index.d.ts +10 -0
  260. package/dist/types/server/react-server/RequestLocale.d.ts +1 -0
  261. package/dist/types/server/react-server/RequestLocaleCache.d.ts +3 -0
  262. package/dist/types/server/react-server/createRequestConfig.d.ts +3 -0
  263. package/dist/types/server/react-server/getConfig.d.ts +13 -0
  264. package/dist/types/server/react-server/getConfigNow.d.ts +4 -0
  265. package/dist/types/server/react-server/getDefaultNow.d.ts +3 -0
  266. package/dist/types/server/react-server/getExtracted.d.ts +10 -0
  267. package/dist/types/server/react-server/getFormats.d.ts +3 -0
  268. package/dist/types/server/react-server/getFormatter.d.ts +10 -0
  269. package/dist/types/server/react-server/getLocale.d.ts +4 -0
  270. package/dist/types/server/react-server/getMessages.d.ts +6 -0
  271. package/dist/types/server/react-server/getNow.d.ts +4 -0
  272. package/dist/types/server/react-server/getRequestConfig.d.ts +35 -0
  273. package/dist/types/server/react-server/getServerExtractor.d.ts +5 -0
  274. package/dist/types/server/react-server/getServerFormatter.d.ts +25 -0
  275. package/dist/types/server/react-server/getServerTranslator.d.ts +4 -0
  276. package/dist/types/server/react-server/getTimeZone.d.ts +4 -0
  277. package/dist/types/server/react-server/getTranslations.d.ts +8 -0
  278. package/dist/types/server/react-server/index.d.ts +12 -0
  279. package/dist/types/server/react-server/validateLocale.d.ts +1 -0
  280. package/dist/types/server.react-client.d.ts +1 -0
  281. package/dist/types/server.react-server.d.ts +1 -0
  282. package/dist/types/shared/NextIntlClientProvider.d.ts +9 -0
  283. package/dist/types/shared/constants.d.ts +1 -0
  284. package/dist/types/shared/types.d.ts +5 -0
  285. package/dist/types/shared/use.d.ts +3 -0
  286. package/dist/types/shared/utils.d.ts +20 -0
  287. package/extractor/catalogLoader.d.ts +4 -0
  288. package/extractor/extractionLoader.d.ts +4 -0
  289. package/extractor.d.ts +2 -0
  290. package/middleware.d.ts +4 -0
  291. package/navigation.d.ts +2 -0
  292. package/package.json +175 -0
  293. package/plugin.d.cts +3 -0
  294. package/plugin.d.ts +4 -0
  295. package/routing.d.ts +2 -0
  296. package/server.d.ts +2 -0
@@ -0,0 +1,80 @@
1
+ import { useRouter, usePathname } from 'next/navigation';
2
+ import { useMemo } from 'react';
3
+ import { useLocale } from 'use-intl';
4
+ import createSharedNavigationFns from '../shared/createSharedNavigationFns.js';
5
+ import syncLocaleCookie from '../shared/syncLocaleCookie.js';
6
+ import { getRoute } from '../shared/utils.js';
7
+ import useBasePathname from './useBasePathname.js';
8
+
9
+ function createNavigation(routing) {
10
+ const {
11
+ Link,
12
+ config,
13
+ getPathname,
14
+ ...redirects
15
+ } = createSharedNavigationFns(useLocale, routing);
16
+
17
+ /** @see https://next-intl.dev/docs/routing/navigation#usepathname */
18
+ function usePathname$1() {
19
+ const pathname = useBasePathname(config);
20
+ const locale = useLocale();
21
+
22
+ // @ts-expect-error -- Mirror the behavior from Next.js, where `null` is returned when `usePathname` is used outside of Next, but the types indicate that a string is always returned.
23
+ return useMemo(() => pathname &&
24
+ // @ts-expect-error -- This is fine
25
+ config.pathnames ? getRoute(locale, pathname,
26
+ // @ts-expect-error -- This is fine
27
+ config.pathnames) : pathname, [locale, pathname]);
28
+ }
29
+ function useRouter$1() {
30
+ const router = useRouter();
31
+ const curLocale = useLocale();
32
+ const nextPathname = usePathname();
33
+ return useMemo(() => {
34
+ function createHandler(fn) {
35
+ return function handler(href, options) {
36
+ const {
37
+ locale: nextLocale,
38
+ ...rest
39
+ } = options || {};
40
+ const pathname = getPathname({
41
+ href,
42
+ locale: nextLocale || curLocale,
43
+ // Always include a prefix when changing locales. Theoretically,
44
+ // this is only necessary for the case described in #2020. However,
45
+ // the full detection is rather expensive, and this behavior is
46
+ // consistent with the `Link` component. The downside is an
47
+ // additional redirect for users in other situations. Locale
48
+ // changes should be rare though, so this might be fine.
49
+ forcePrefix: nextLocale != null || undefined
50
+ });
51
+ const args = [pathname];
52
+ if (Object.keys(rest).length > 0) {
53
+ // @ts-expect-error -- This is fine
54
+ args.push(rest);
55
+ }
56
+ syncLocaleCookie(config.localeCookie, nextPathname, curLocale, nextLocale);
57
+ fn(...args);
58
+ };
59
+ }
60
+ return {
61
+ ...router,
62
+ /** @see https://next-intl.dev/docs/routing/navigation#userouter */
63
+ push: createHandler(router.push),
64
+ /** @see https://next-intl.dev/docs/routing/navigation#userouter */
65
+ replace: createHandler(router.replace),
66
+ /** @see https://next-intl.dev/docs/routing/navigation#userouter */
67
+ prefetch: createHandler(router.prefetch)
68
+ };
69
+ }, [curLocale, nextPathname, router]);
70
+ }
71
+ return {
72
+ ...redirects,
73
+ Link,
74
+ usePathname: usePathname$1,
75
+ useRouter: useRouter$1,
76
+ getPathname
77
+ };
78
+ }
79
+
80
+ export { createNavigation as default };
@@ -0,0 +1,36 @@
1
+ import { usePathname } from 'next/navigation';
2
+ import { useMemo } from 'react';
3
+ import { useLocale } from 'use-intl';
4
+ import { hasPathnamePrefixed, unprefixPathname, getLocalePrefix, getLocaleAsPrefix } from '../../shared/utils.js';
5
+
6
+ function useBasePathname(config) {
7
+ // The types aren't entirely correct here. Outside of Next.js
8
+ // `useParams` can be called, but the return type is `null`.
9
+
10
+ // Notes on `useNextPathname`:
11
+ // - Types aren't entirely correct. Outside of Next.js the
12
+ // hook will return `null` (e.g. unit tests)
13
+ // - A base path is stripped from the result
14
+ // - Rewrites *are* taken into account (i.e. the pathname
15
+ // that the user sees in the browser is returned)
16
+ const pathname = usePathname();
17
+ const locale = useLocale();
18
+ return useMemo(() => {
19
+ if (!pathname) return pathname;
20
+ let unlocalizedPathname = pathname;
21
+ const prefix = getLocalePrefix(locale, config.localePrefix);
22
+ const isPathnamePrefixed = hasPathnamePrefixed(prefix, pathname);
23
+ if (isPathnamePrefixed) {
24
+ unlocalizedPathname = unprefixPathname(pathname, prefix);
25
+ } else if (config.localePrefix.mode !== 'never' && config.localePrefix.prefixes) {
26
+ // Workaround for https://github.com/vercel/next.js/issues/73085
27
+ const localeAsPrefix = getLocaleAsPrefix(locale);
28
+ if (hasPathnamePrefixed(localeAsPrefix, pathname)) {
29
+ unlocalizedPathname = unprefixPathname(pathname, localeAsPrefix);
30
+ }
31
+ }
32
+ return unlocalizedPathname;
33
+ }, [config.localePrefix, locale, pathname]);
34
+ }
35
+
36
+ export { useBasePathname as default };
@@ -0,0 +1,22 @@
1
+ import createSharedNavigationFns from '../shared/createSharedNavigationFns.js';
2
+ import getServerLocale from './getServerLocale.js';
3
+
4
+ function createNavigation(routing) {
5
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
+ const {
7
+ config,
8
+ ...fns
9
+ } = createSharedNavigationFns(getServerLocale, routing);
10
+ function notSupported(hookName) {
11
+ return () => {
12
+ throw new Error(`\`${hookName}\` is not supported in Server Components. You can use this hook if you convert the calling component to a Client Component.`);
13
+ };
14
+ }
15
+ return {
16
+ ...fns,
17
+ usePathname: notSupported('usePathname'),
18
+ useRouter: notSupported('useRouter')
19
+ };
20
+ }
21
+
22
+ export { createNavigation as default };
@@ -0,0 +1,12 @@
1
+ import getConfig from '../../server/react-server/getConfig.js';
2
+
3
+ /**
4
+ * This is only moved to a separate module for easier mocking in
5
+ * `../createNavigatoin.test.tsx` in order to avoid suspending.
6
+ */
7
+ async function getServerLocale() {
8
+ const config = await getConfig();
9
+ return config.locale;
10
+ }
11
+
12
+ export { getServerLocale as default };
@@ -0,0 +1,51 @@
1
+ "use client";
2
+ import NextLink from 'next/link';
3
+ import { usePathname } from 'next/navigation';
4
+ import { forwardRef } from 'react';
5
+ import { useLocale } from 'use-intl';
6
+ import syncLocaleCookie from './syncLocaleCookie.js';
7
+ import { jsx } from 'react/jsx-runtime';
8
+
9
+ function BaseLink({
10
+ href,
11
+ locale,
12
+ localeCookie,
13
+ onClick,
14
+ prefetch,
15
+ ...rest
16
+ }, ref) {
17
+ const curLocale = useLocale();
18
+ const isChangingLocale = locale != null && locale !== curLocale;
19
+
20
+ // The types aren't entirely correct here. Outside of Next.js
21
+ // `useParams` can be called, but the return type is `null`.
22
+ const pathname = usePathname();
23
+ function onLinkClick(event) {
24
+ // Even though we force a prefix when changing locales,
25
+ // this could be a cache hit of the client-side router,
26
+ // therefore we sync the cookie to ensure it's up to date.
27
+ syncLocaleCookie(localeCookie, pathname, curLocale, locale);
28
+ if (onClick) onClick(event);
29
+ }
30
+ if (isChangingLocale) {
31
+ if (prefetch && "development" !== 'production') {
32
+ console.error('The `prefetch` prop is currently not supported when using the `locale` prop on `Link` to switch the locale.`');
33
+ }
34
+ prefetch = false;
35
+ }
36
+
37
+ // Somehow the types for `next/link` don't work as expected
38
+ // when `moduleResolution: "nodenext"` is used.
39
+ const Link = NextLink;
40
+ return /*#__PURE__*/jsx(Link, {
41
+ ref: ref,
42
+ href: href,
43
+ hrefLang: isChangingLocale ? locale : undefined,
44
+ onClick: onLinkClick,
45
+ prefetch: prefetch,
46
+ ...rest
47
+ });
48
+ }
49
+ var BaseLink$1 = /*#__PURE__*/forwardRef(BaseLink);
50
+
51
+ export { BaseLink$1 as default };
@@ -0,0 +1,105 @@
1
+ import { redirect, permanentRedirect } from 'next/navigation';
2
+ import { forwardRef } from 'react';
3
+ import { receiveRoutingConfig } from '../../routing/config.js';
4
+ import use from '../../shared/use.js';
5
+ import { isLocalizableHref, isPromise } from '../../shared/utils.js';
6
+ import BaseLink from './BaseLink.js';
7
+ import { validateReceivedConfig, serializeSearchParams, compileLocalizedPathname, applyPathnamePrefix, normalizeNameOrNameWithParams } from './utils.js';
8
+ import { jsx } from 'react/jsx-runtime';
9
+
10
+ /**
11
+ * Shared implementations for `react-server` and `react-client`
12
+ */
13
+ function createSharedNavigationFns(getLocale, routing) {
14
+ const config = receiveRoutingConfig(routing || {});
15
+ {
16
+ validateReceivedConfig(config);
17
+ }
18
+ const pathnames = config.pathnames;
19
+ function Link({
20
+ href,
21
+ locale,
22
+ ...rest
23
+ }, ref) {
24
+ let pathname, params;
25
+ if (typeof href === 'object') {
26
+ pathname = href.pathname;
27
+ // @ts-expect-error -- This is ok
28
+ params = href.params;
29
+ } else {
30
+ pathname = href;
31
+ }
32
+
33
+ // @ts-expect-error -- This is ok
34
+ const isLocalizable = isLocalizableHref(href);
35
+ const localePromiseOrValue = getLocale();
36
+ const curLocale = isPromise(localePromiseOrValue) ? use(localePromiseOrValue) : localePromiseOrValue;
37
+ const finalPathname = isLocalizable ? getPathname({
38
+ locale: locale || curLocale,
39
+ // @ts-expect-error -- This is ok
40
+ href: pathnames == null ? pathname : {
41
+ pathname,
42
+ params
43
+ },
44
+ // Always include a prefix when changing locales
45
+ forcePrefix: locale != null || undefined
46
+ }) : pathname;
47
+ return /*#__PURE__*/jsx(BaseLink, {
48
+ ref: ref
49
+ // @ts-expect-error -- This is ok
50
+ ,
51
+ href: typeof href === 'object' ? {
52
+ ...href,
53
+ pathname: finalPathname
54
+ } : finalPathname,
55
+ locale: locale,
56
+ localeCookie: config.localeCookie,
57
+ ...rest
58
+ });
59
+ }
60
+ const LinkWithRef = /*#__PURE__*/forwardRef(Link);
61
+ function getPathname(args) {
62
+ const {
63
+ forcePrefix,
64
+ href,
65
+ locale
66
+ } = args;
67
+ let pathname;
68
+ if (pathnames == null) {
69
+ if (typeof href === 'object') {
70
+ pathname = href.pathname;
71
+ if (href.query) {
72
+ pathname += serializeSearchParams(href.query);
73
+ }
74
+ } else {
75
+ pathname = href;
76
+ }
77
+ } else {
78
+ pathname = compileLocalizedPathname({
79
+ locale,
80
+ // @ts-expect-error -- This is ok
81
+ ...normalizeNameOrNameWithParams(href),
82
+ // @ts-expect-error -- This is ok
83
+ pathnames: config.pathnames
84
+ });
85
+ }
86
+ return applyPathnamePrefix(pathname, locale, config, forcePrefix);
87
+ }
88
+ function getRedirectFn(fn) {
89
+ /** @see https://next-intl.dev/docs/routing/navigation#redirect */
90
+ return function redirectFn(args, ...rest) {
91
+ return fn(getPathname(args), ...rest);
92
+ };
93
+ }
94
+ const redirect$1 = getRedirectFn(redirect);
95
+ const permanentRedirect$1 = getRedirectFn(permanentRedirect);
96
+ return {
97
+ config,
98
+ Link: LinkWithRef,
99
+ redirect: redirect$1,
100
+ permanentRedirect: permanentRedirect$1,
101
+ getPathname
102
+ };
103
+ }
104
+
105
+ export { createSharedNavigationFns as default };
@@ -0,0 +1,47 @@
1
+ import { getBasePath } from './utils.js';
2
+
3
+ /**
4
+ * We have to keep the cookie value in sync as Next.js might
5
+ * skip a request to the server due to its router cache.
6
+ * See https://github.com/amannn/next-intl/issues/786.
7
+ */
8
+ function syncLocaleCookie(localeCookie, pathname, locale, nextLocale) {
9
+ const isSwitchingLocale = nextLocale !== locale && nextLocale != null;
10
+ if (!localeCookie || !isSwitchingLocale ||
11
+ // Theoretical case, we always have a pathname in a real app,
12
+ // only not when running e.g. in a simulated test environment
13
+ !pathname) {
14
+ return;
15
+ }
16
+ const basePath = getBasePath(pathname);
17
+ const hasBasePath = basePath !== '';
18
+ const defaultPath = hasBasePath ? basePath : '/';
19
+ const {
20
+ name,
21
+ ...rest
22
+ } = localeCookie;
23
+ if (!rest.path) {
24
+ rest.path = defaultPath;
25
+ }
26
+ let localeCookieString = `${name}=${nextLocale};`;
27
+ for (const [key, value] of Object.entries(rest)) {
28
+ // Map object properties to cookie properties.
29
+ // Interestingly, `maxAge` corresponds to `max-age`,
30
+ // while `sameSite` corresponds to `SameSite`.
31
+ // Also, keys are case-insensitive.
32
+ const targetKey = key === 'maxAge' ? 'max-age' : key;
33
+ localeCookieString += `${targetKey}`;
34
+ if (typeof value !== 'boolean') {
35
+ localeCookieString += '=' + value;
36
+ }
37
+
38
+ // A trailing ";" is allowed by browsers
39
+ localeCookieString += ';';
40
+ }
41
+
42
+ // Note that writing to `document.cookie` doesn't overwrite all
43
+ // cookies, but only the ones referenced via the name here.
44
+ document.cookie = localeCookieString;
45
+ }
46
+
47
+ export { syncLocaleCookie as default };
@@ -0,0 +1,165 @@
1
+ import { getSortedPathnames, matchesPathname, isLocalizableHref, prefixPathname, getLocalizedTemplate, normalizeTrailingSlash, getLocalePrefix } from '../../shared/utils.js';
2
+
3
+ // Minor false positive: A route that has both optional and
4
+ // required params will allow optional params.
5
+
6
+ // For `Link`
7
+
8
+ // For `getPathname` (hence also its consumers: `redirect`, `useRouter`, …)
9
+
10
+ function normalizeNameOrNameWithParams(href) {
11
+ return typeof href === 'string' ? {
12
+ pathname: href
13
+ } : href;
14
+ }
15
+ function serializeSearchParams(searchParams) {
16
+ function serializeValue(value) {
17
+ return String(value);
18
+ }
19
+ const urlSearchParams = new URLSearchParams();
20
+ for (const [key, value] of Object.entries(searchParams)) {
21
+ if (Array.isArray(value)) {
22
+ value.forEach(cur => {
23
+ urlSearchParams.append(key, serializeValue(cur));
24
+ });
25
+ } else {
26
+ urlSearchParams.set(key, serializeValue(value));
27
+ }
28
+ }
29
+ return '?' + urlSearchParams.toString();
30
+ }
31
+ function compileLocalizedPathname({
32
+ pathname,
33
+ locale,
34
+ params,
35
+ pathnames,
36
+ query
37
+ }) {
38
+ function compilePath(value) {
39
+ const pathnameConfig = pathnames[value];
40
+ let compiled;
41
+ if (pathnameConfig) {
42
+ const template = getLocalizedTemplate(pathnameConfig, locale, value);
43
+ compiled = template;
44
+ if (params) {
45
+ Object.entries(params).forEach(([key, paramValue]) => {
46
+ let regexp, replacer;
47
+ if (Array.isArray(paramValue)) {
48
+ regexp = `(\\[)?\\[...${key}\\](\\])?`;
49
+ replacer = paramValue.map(v => String(v)).join('/');
50
+ } else {
51
+ regexp = `\\[${key}\\]`;
52
+ replacer = String(paramValue);
53
+ }
54
+ compiled = compiled.replace(new RegExp(regexp, 'g'), replacer);
55
+ });
56
+ }
57
+
58
+ // Clean up optional catch-all segments that were not replaced
59
+ compiled = compiled.replace(/\[\[\.\.\..+\]\]/g, '');
60
+ if (compiled.includes('[')) {
61
+ // Next.js throws anyway, therefore better provide a more helpful error message
62
+ throw new Error(`Insufficient params provided for localized pathname.\nTemplate: ${template}\nParams: ${JSON.stringify(params)}`);
63
+ }
64
+ compiled = encodePathname(compiled);
65
+ } else {
66
+ // Unknown pathnames
67
+ compiled = value;
68
+ }
69
+ compiled = normalizeTrailingSlash(compiled);
70
+ if (query) {
71
+ // This also encodes non-ASCII characters by
72
+ // using `new URLSearchParams()` internally
73
+ compiled += serializeSearchParams(query);
74
+ }
75
+ return compiled;
76
+ }
77
+ if (typeof pathname === 'string') {
78
+ return compilePath(pathname);
79
+ } else {
80
+ const {
81
+ pathname: internalPathname,
82
+ ...rest
83
+ } = pathname;
84
+ const compiled = compilePath(internalPathname);
85
+ const result = {
86
+ ...rest,
87
+ pathname: compiled
88
+ };
89
+ return result;
90
+ }
91
+ }
92
+ function encodePathname(pathname) {
93
+ // Generally, to comply with RFC 3986 and Google's best practices for URL structures
94
+ // (https://developers.google.com/search/docs/crawling-indexing/url-structure),
95
+ // we should always encode non-ASCII characters.
96
+ //
97
+ // There are two places where next-intl interacts with potentially non-ASCII URLs:
98
+ // 1. Middleware: When mapping a localized pathname to a non-localized pathname internally
99
+ // 2. Navigation APIs: When generating a URLs to be used for <Link /> & friends
100
+ //
101
+ // Next.js normalizes incoming pathnames to always be encoded, therefore we can safely
102
+ // decode them there (see middleware.tsx). On the other hand, Next.js doesn't consistently
103
+ // encode non-ASCII characters that are passed to navigation APIs:
104
+ // 1. <Link /> doesn't encode non-ASCII characters
105
+ // 2. useRouter() uses `new URL()` internally, which will encode—but only if necessary
106
+ // 3. redirect() uses useRouter() on the client, but on the server side only
107
+ // assigns the location header without encoding.
108
+ //
109
+ // In addition to this, for getPathname() we need to encode non-ASCII characters.
110
+ //
111
+ // Therefore, the bottom line is that next-intl should take care of encoding non-ASCII
112
+ // characters in all cases, but can rely on `new URL()` to not double-encode characters.
113
+ return new URL(pathname, 'http://l').pathname;
114
+ }
115
+ function getRoute(locale, pathname, pathnames) {
116
+ const sortedPathnames = getSortedPathnames(Object.keys(pathnames));
117
+ const decoded = decodeURI(pathname);
118
+ for (const internalPathname of sortedPathnames) {
119
+ const localizedPathnamesOrPathname = pathnames[internalPathname];
120
+ if (typeof localizedPathnamesOrPathname === 'string') {
121
+ const localizedPathname = localizedPathnamesOrPathname;
122
+ if (matchesPathname(localizedPathname, decoded)) {
123
+ return internalPathname;
124
+ }
125
+ } else {
126
+ if (matchesPathname(getLocalizedTemplate(localizedPathnamesOrPathname, locale, internalPathname), decoded)) {
127
+ return internalPathname;
128
+ }
129
+ }
130
+ }
131
+ return pathname;
132
+ }
133
+ function getBasePath(pathname, windowPathname = window.location.pathname) {
134
+ if (pathname === '/') {
135
+ return windowPathname;
136
+ } else {
137
+ return windowPathname.replace(pathname, '');
138
+ }
139
+ }
140
+ function applyPathnamePrefix(pathname, locale, routing, force) {
141
+ const {
142
+ mode
143
+ } = routing.localePrefix;
144
+ let shouldPrefix;
145
+ if (force !== undefined) {
146
+ shouldPrefix = force;
147
+ } else if (isLocalizableHref(pathname)) {
148
+ if (mode === 'always') {
149
+ shouldPrefix = true;
150
+ } else if (mode === 'as-needed') {
151
+ shouldPrefix = routing.domains ?
152
+ // Since locales are unique per domain, any locale that is a
153
+ // default locale of a domain doesn't require a prefix
154
+ !routing.domains.some(cur => cur.defaultLocale === locale) : locale !== routing.defaultLocale;
155
+ }
156
+ }
157
+ return shouldPrefix ? prefixPathname(getLocalePrefix(locale, routing.localePrefix), pathname) : pathname;
158
+ }
159
+ function validateReceivedConfig(config) {
160
+ if (config.localePrefix?.mode === 'as-needed' && !('defaultLocale' in config)) {
161
+ throw new Error("`localePrefix: 'as-needed' requires a `defaultLocale`.");
162
+ }
163
+ }
164
+
165
+ export { applyPathnamePrefix, compileLocalizedPathname, getBasePath, getRoute, normalizeNameOrNameWithParams, serializeSearchParams, validateReceivedConfig };
@@ -0,0 +1 @@
1
+ export { default as createNavigation } from './navigation/react-client/createNavigation.js';
@@ -0,0 +1 @@
1
+ export { default as createNavigation } from './navigation/react-server/createNavigation.js';
@@ -0,0 +1,10 @@
1
+ // Avoid rollup's `replace` plugin to compile this away
2
+ const nodeEnvKey = 'NODE_ENV'.trim();
3
+
4
+ // We avoid reading `argv.includes('dev')` related to
5
+ // https://github.com/amannn/next-intl/issues/2006
6
+ const isDevelopment = process.env[nodeEnvKey] === 'development';
7
+ const isNextBuild = process.argv.includes('build');
8
+ const isDevelopmentOrNextBuild = isDevelopment || isNextBuild;
9
+
10
+ export { isDevelopment, isDevelopmentOrNextBuild, isNextBuild };
@@ -0,0 +1,26 @@
1
+ import initExtractionCompiler from './extractor/initExtractionCompiler.js';
2
+ import getNextConfig from './getNextConfig.js';
3
+ import { warn } from './utils.js';
4
+ import createMessagesDeclaration from './declaration/createMessagesDeclaration.js';
5
+
6
+ function initPlugin(pluginConfig, nextConfig) {
7
+ if (nextConfig?.i18n != null) {
8
+ warn("An `i18n` property was found in your Next.js config. This likely causes conflicts and should therefore be removed if you use the App Router.\n\nIf you're in progress of migrating from the Pages Router, you can refer to this example: https://next-intl.dev/examples#app-router-migration\n");
9
+ }
10
+ const messagesPathOrPaths = pluginConfig.experimental?.createMessagesDeclaration;
11
+ if (messagesPathOrPaths) {
12
+ createMessagesDeclaration(typeof messagesPathOrPaths === 'string' ? [messagesPathOrPaths] : messagesPathOrPaths);
13
+ }
14
+ initExtractionCompiler(pluginConfig);
15
+ return getNextConfig(pluginConfig, nextConfig);
16
+ }
17
+ function createNextIntlPlugin(i18nPathOrConfig = {}) {
18
+ const config = typeof i18nPathOrConfig === 'string' ? {
19
+ requestConfig: i18nPathOrConfig
20
+ } : i18nPathOrConfig;
21
+ return function withNextIntl(nextConfig) {
22
+ return initPlugin(config, nextConfig);
23
+ };
24
+ }
25
+
26
+ export { createNextIntlPlugin as default };
@@ -0,0 +1,70 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { once, throwError } from '../utils.js';
4
+ import watchFile from '../watchFile.js';
5
+
6
+ const runOnce = once('_NEXT_INTL_COMPILE_MESSAGES');
7
+ function createMessagesDeclaration(messagesPaths) {
8
+ // Instead of running _only_ in certain cases, it's
9
+ // safer to _avoid_ running for certain known cases.
10
+ // https://github.com/amannn/next-intl/issues/2006
11
+ const shouldBailOut = ['info', 'start'
12
+
13
+ // Note: These commands don't consult the
14
+ // Next.js config, so we can't detect them here.
15
+ // - telemetry
16
+ // - lint
17
+ //
18
+ // What remains are:
19
+ // - dev
20
+ // - build
21
+ // - typegen
22
+ ].some(arg => process.argv.includes(arg));
23
+ if (shouldBailOut) {
24
+ return;
25
+ }
26
+ runOnce(() => {
27
+ for (const messagesPath of messagesPaths) {
28
+ const fullPath = path.resolve(messagesPath);
29
+ if (!fs.existsSync(fullPath)) {
30
+ throwError(`\`createMessagesDeclaration\` points to a non-existent file: ${fullPath}`);
31
+ }
32
+ if (!fullPath.endsWith('.json')) {
33
+ throwError(`\`createMessagesDeclaration\` needs to point to a JSON file. Received: ${fullPath}`);
34
+ }
35
+
36
+ // Keep this as a runtime check and don't replace
37
+ // this with a constant during the build process
38
+ const env = process.env['NODE_ENV'.trim()];
39
+ compileDeclaration(messagesPath);
40
+ if (env === 'development') {
41
+ startWatching(messagesPath);
42
+ }
43
+ }
44
+ });
45
+ }
46
+ function startWatching(messagesPath) {
47
+ const watcher = watchFile(messagesPath, () => {
48
+ compileDeclaration(messagesPath, true);
49
+ });
50
+ process.on('exit', () => {
51
+ watcher.close();
52
+ });
53
+ }
54
+ function compileDeclaration(messagesPath, async = false) {
55
+ const declarationPath = messagesPath.replace(/\.json$/, '.d.json.ts');
56
+ function createDeclaration(content) {
57
+ return `// This file is auto-generated by next-intl, do not edit directly.
58
+ // See: https://next-intl.dev/docs/workflows/typescript#messages-arguments
59
+
60
+ declare const messages: ${content.trim()};
61
+ export default messages;`;
62
+ }
63
+ if (async) {
64
+ return fs.promises.readFile(messagesPath, 'utf-8').then(content => fs.promises.writeFile(declarationPath, createDeclaration(content)));
65
+ }
66
+ const content = fs.readFileSync(messagesPath, 'utf-8');
67
+ fs.writeFileSync(declarationPath, createDeclaration(content));
68
+ }
69
+
70
+ export { createMessagesDeclaration as default };