reroute-js 0.45.11 → 0.46.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 (244) hide show
  1. package/README.md +100 -2
  2. package/_/blog/src/client/routes/blog/[layout].tsx +45 -13
  3. package/_/blog/src/client/routes/blog/content/pt-BR/1-hello-world.tsx +27 -0
  4. package/_/blog/src/client/routes/index.tsx +4 -4
  5. package/_/search/src/client/routes/docs/content/content-collections.md +18 -0
  6. package/cli/bin.d.ts +2 -2
  7. package/cli/bin.js +1175 -431
  8. package/cli/bin.js.map +33 -24
  9. package/cli/index.d.ts +2 -2
  10. package/cli/index.js +5 -5
  11. package/cli/index.js.map +1 -1
  12. package/cli/src/cli.d.ts +2 -2
  13. package/cli/src/commands/analyze.d.ts +2 -2
  14. package/cli/src/commands/build.d.ts +2 -2
  15. package/cli/src/commands/dev.d.ts +2 -2
  16. package/cli/src/commands/gen.d.ts +2 -2
  17. package/cli/src/commands/gen.d.ts.map +1 -1
  18. package/cli/src/commands/index.d.ts +2 -2
  19. package/cli/src/commands/init.d.ts +2 -2
  20. package/cli/src/commands/lib/assets.d.ts +2 -2
  21. package/cli/src/commands/lib/bundler.d.ts +2 -2
  22. package/cli/src/commands/lib/command.d.ts +2 -2
  23. package/cli/src/commands/lib/env.d.ts +2 -2
  24. package/cli/src/commands/lib/index.d.ts +2 -2
  25. package/cli/src/commands/lib/log.d.ts +2 -2
  26. package/cli/src/commands/lib/markdown/availability.d.ts +2 -2
  27. package/cli/src/commands/lib/markdown/index.d.ts +2 -2
  28. package/cli/src/commands/lib/markdown/processor.d.ts +2 -2
  29. package/cli/src/commands/lib/production.d.ts +2 -2
  30. package/cli/src/commands/lib/server.d.ts +2 -2
  31. package/cli/src/commands/lib/streaming/analyzer.d.ts +2 -2
  32. package/cli/src/commands/lib/streaming/suspense.d.ts +2 -2
  33. package/cli/src/commands/lib/tailwind.d.ts +2 -2
  34. package/cli/src/commands/lib/terminal-ui.d.ts +2 -2
  35. package/cli/src/commands/lib/version.d.ts +2 -2
  36. package/cli/src/commands/og.d.ts +2 -2
  37. package/cli/src/commands/start.d.ts +2 -2
  38. package/cli/src/index.d.ts +2 -2
  39. package/core/index.d.ts +2 -2
  40. package/core/index.js +827 -192
  41. package/core/index.js.map +32 -23
  42. package/core/src/bundler/hash.d.ts +2 -2
  43. package/core/src/bundler/index.d.ts +2 -2
  44. package/core/src/config.d.ts +6 -3
  45. package/core/src/config.d.ts.map +1 -1
  46. package/core/src/content/discovery.d.ts +2 -2
  47. package/core/src/content/index.d.ts +2 -2
  48. package/core/src/content/metadata.d.ts +2 -2
  49. package/core/src/i18n/catalog.d.ts +17 -0
  50. package/core/src/i18n/catalog.d.ts.map +1 -0
  51. package/core/src/i18n/discover.d.ts +19 -0
  52. package/core/src/i18n/discover.d.ts.map +1 -0
  53. package/core/src/i18n/index.d.ts +17 -0
  54. package/core/src/i18n/index.d.ts.map +1 -0
  55. package/core/src/i18n/messages.d.ts +18 -0
  56. package/core/src/i18n/messages.d.ts.map +1 -0
  57. package/core/src/i18n/negotiate.d.ts +18 -0
  58. package/core/src/i18n/negotiate.d.ts.map +1 -0
  59. package/core/src/i18n/pathname.d.ts +34 -0
  60. package/core/src/i18n/pathname.d.ts.map +1 -0
  61. package/core/src/i18n/resolve.d.ts +22 -0
  62. package/core/src/i18n/resolve.d.ts.map +1 -0
  63. package/core/src/i18n/types.d.ts +68 -0
  64. package/core/src/i18n/types.d.ts.map +1 -0
  65. package/core/src/index.d.ts +3 -2
  66. package/core/src/index.d.ts.map +1 -1
  67. package/core/src/llms/extractor.d.ts +2 -2
  68. package/core/src/llms/formatter.d.ts +2 -2
  69. package/core/src/llms/full-generator.d.ts +2 -2
  70. package/core/src/llms/index-generator.d.ts +2 -2
  71. package/core/src/llms/index.d.ts +2 -2
  72. package/core/src/og/discovery.d.ts +2 -2
  73. package/core/src/og/discovery.d.ts.map +1 -1
  74. package/core/src/og/index.d.ts +2 -2
  75. package/core/src/og/meta.d.ts +2 -2
  76. package/core/src/og/render.d.ts +2 -2
  77. package/core/src/og/types.d.ts +2 -2
  78. package/core/src/robots/discovery.d.ts +2 -2
  79. package/core/src/robots/generator.d.ts +2 -2
  80. package/core/src/robots/index.d.ts +2 -2
  81. package/core/src/robots/policies.d.ts +2 -2
  82. package/core/src/rss/discovery.d.ts +4 -2
  83. package/core/src/rss/discovery.d.ts.map +1 -1
  84. package/core/src/rss/generator.d.ts +2 -2
  85. package/core/src/rss/index.d.ts +2 -2
  86. package/core/src/sitemap/discovery.d.ts +7 -2
  87. package/core/src/sitemap/discovery.d.ts.map +1 -1
  88. package/core/src/sitemap/generator.d.ts +2 -2
  89. package/core/src/sitemap/generator.d.ts.map +1 -1
  90. package/core/src/sitemap/index.d.ts +2 -2
  91. package/core/src/ssr/index.d.ts +2 -2
  92. package/core/src/ssr/lib/cache.d.ts +2 -2
  93. package/core/src/ssr/lib/cleanup.d.ts +2 -2
  94. package/core/src/ssr/lib/collections.d.ts +2 -2
  95. package/core/src/ssr/lib/compression.d.ts +2 -2
  96. package/core/src/ssr/lib/compute/content.d.ts +2 -9
  97. package/core/src/ssr/lib/compute/content.d.ts.map +1 -1
  98. package/core/src/ssr/lib/compute/index.d.ts +2 -2
  99. package/core/src/ssr/lib/compute/index.d.ts.map +1 -1
  100. package/core/src/ssr/lib/compute/layouts.d.ts +2 -2
  101. package/core/src/ssr/lib/compute/routes.d.ts +2 -2
  102. package/core/src/ssr/lib/compute/routes.d.ts.map +1 -1
  103. package/core/src/ssr/lib/content-path.d.ts +22 -0
  104. package/core/src/ssr/lib/content-path.d.ts.map +1 -0
  105. package/core/src/ssr/lib/data.d.ts +2 -2
  106. package/core/src/ssr/lib/data.d.ts.map +1 -1
  107. package/core/src/ssr/lib/html.d.ts +2 -2
  108. package/core/src/ssr/lib/imports.d.ts +2 -2
  109. package/core/src/ssr/lib/index.d.ts +3 -2
  110. package/core/src/ssr/lib/index.d.ts.map +1 -1
  111. package/core/src/ssr/lib/layouts.d.ts +2 -2
  112. package/core/src/ssr/lib/metadata.d.ts +2 -2
  113. package/core/src/ssr/lib/metadata.d.ts.map +1 -1
  114. package/core/src/ssr/lib/mime.d.ts +2 -2
  115. package/core/src/ssr/lib/modules.d.ts +4 -4
  116. package/core/src/ssr/lib/modules.d.ts.map +1 -1
  117. package/core/src/ssr/lib/path.d.ts +2 -2
  118. package/core/src/ssr/lib/preload.d.ts +2 -2
  119. package/core/src/ssr/lib/preload.d.ts.map +1 -1
  120. package/core/src/ssr/lib/route-match.d.ts +20 -0
  121. package/core/src/ssr/lib/route-match.d.ts.map +1 -0
  122. package/core/src/ssr/lib/scripts/collections.d.ts +2 -2
  123. package/core/src/ssr/lib/scripts/data.d.ts +3 -3
  124. package/core/src/ssr/lib/scripts/data.d.ts.map +1 -1
  125. package/core/src/ssr/lib/scripts/escape.d.ts +2 -2
  126. package/core/src/ssr/lib/scripts/feeds.d.ts +2 -2
  127. package/core/src/ssr/lib/scripts/index.d.ts +2 -2
  128. package/core/src/ssr/lib/seed.d.ts +2 -2
  129. package/core/src/ssr/lib/seed.d.ts.map +1 -1
  130. package/core/src/ssr/lib/serialize.d.ts +2 -2
  131. package/core/src/ssr/lib/setup.d.ts +3 -3
  132. package/core/src/ssr/lib/setup.d.ts.map +1 -1
  133. package/core/src/ssr/lib/styles.d.ts +2 -2
  134. package/core/src/ssr/lib/template.d.ts +2 -2
  135. package/core/src/ssr/lib/types.d.ts +2 -2
  136. package/core/src/ssr/render.d.ts +4 -2
  137. package/core/src/ssr/render.d.ts.map +1 -1
  138. package/core/src/ssr/stream.d.ts +4 -2
  139. package/core/src/ssr/stream.d.ts.map +1 -1
  140. package/elysia/index.d.ts +2 -2
  141. package/elysia/index.js +1072 -276
  142. package/elysia/index.js.map +37 -27
  143. package/elysia/src/index.d.ts +2 -2
  144. package/elysia/src/libs/assets.d.ts +2 -2
  145. package/elysia/src/libs/cache.d.ts +2 -2
  146. package/elysia/src/libs/caching.d.ts +2 -2
  147. package/elysia/src/libs/http.d.ts +2 -2
  148. package/elysia/src/libs/i18n.d.ts +26 -0
  149. package/elysia/src/libs/i18n.d.ts.map +1 -0
  150. package/elysia/src/libs/image.d.ts +2 -2
  151. package/elysia/src/libs/index.d.ts +2 -2
  152. package/elysia/src/libs/llms.d.ts +2 -2
  153. package/elysia/src/libs/response.d.ts +2 -2
  154. package/elysia/src/libs/serving.d.ts +2 -2
  155. package/elysia/src/plugin.d.ts +2 -2
  156. package/elysia/src/routes/artifacts.d.ts +2 -2
  157. package/elysia/src/routes/content.d.ts +2 -2
  158. package/elysia/src/routes/image.d.ts +2 -2
  159. package/elysia/src/routes/index.d.ts +2 -2
  160. package/elysia/src/routes/internal.d.ts +2 -2
  161. package/elysia/src/routes/llms.d.ts +2 -2
  162. package/elysia/src/routes/og.d.ts +2 -2
  163. package/elysia/src/routes/og.d.ts.map +1 -1
  164. package/elysia/src/routes/redirects.d.ts +2 -2
  165. package/elysia/src/routes/robots.d.ts +2 -2
  166. package/elysia/src/routes/rss.d.ts +2 -2
  167. package/elysia/src/routes/rss.d.ts.map +1 -1
  168. package/elysia/src/routes/search.d.ts +2 -2
  169. package/elysia/src/routes/search.d.ts.map +1 -1
  170. package/elysia/src/routes/sitemap.d.ts +2 -2
  171. package/elysia/src/routes/ssr.d.ts +2 -2
  172. package/elysia/src/routes/ssr.d.ts.map +1 -1
  173. package/elysia/src/routes/static.d.ts +2 -2
  174. package/elysia/src/types.d.ts +2 -2
  175. package/package.json +7 -6
  176. package/react/index.d.ts +2 -2
  177. package/react/index.js +565 -171
  178. package/react/index.js.map +12 -10
  179. package/react/src/components/ClientOnly.d.ts +2 -2
  180. package/react/src/components/ContentRoute.d.ts +3 -3
  181. package/react/src/components/ContentRoute.d.ts.map +1 -1
  182. package/react/src/components/Image.d.ts +2 -2
  183. package/react/src/components/LazyRoute.d.ts +2 -2
  184. package/react/src/components/Link.d.ts +2 -2
  185. package/react/src/components/Link.d.ts.map +1 -1
  186. package/react/src/components/Markdown.d.ts +2 -2
  187. package/react/src/components/Outlet.d.ts +2 -2
  188. package/react/src/components/index.d.ts +2 -2
  189. package/react/src/hooks/index.d.ts +2 -2
  190. package/react/src/hooks/useContent.d.ts +2 -2
  191. package/react/src/hooks/useContent.d.ts.map +1 -1
  192. package/react/src/hooks/useData.d.ts +2 -2
  193. package/react/src/hooks/useFeed.d.ts +2 -2
  194. package/react/src/hooks/useLayoutData.d.ts +2 -2
  195. package/react/src/hooks/useLlms.d.ts +2 -2
  196. package/react/src/hooks/useNavigate.d.ts +2 -2
  197. package/react/src/hooks/useParams.d.ts +2 -2
  198. package/react/src/hooks/useRouter.d.ts +2 -2
  199. package/react/src/hooks/useSearch.d.ts +2 -2
  200. package/react/src/hooks/useSearch.d.ts.map +1 -1
  201. package/react/src/hooks/useSearchParams.d.ts +2 -2
  202. package/react/src/hooks/useToc.d.ts +2 -2
  203. package/react/src/i18n/LocaleProvider.d.ts +49 -0
  204. package/react/src/i18n/LocaleProvider.d.ts.map +1 -0
  205. package/react/src/i18n/helpers.d.ts +24 -0
  206. package/react/src/i18n/helpers.d.ts.map +1 -0
  207. package/react/src/i18n/index.d.ts +13 -0
  208. package/react/src/i18n/index.d.ts.map +1 -0
  209. package/react/src/index.d.ts +3 -2
  210. package/react/src/index.d.ts.map +1 -1
  211. package/react/src/lib/collection.d.ts +2 -2
  212. package/react/src/lib/content.d.ts +4 -3
  213. package/react/src/lib/content.d.ts.map +1 -1
  214. package/react/src/lib/head.d.ts +2 -2
  215. package/react/src/lib/index.d.ts +2 -2
  216. package/react/src/lib/lazy-route.d.ts +2 -2
  217. package/react/src/lib/route-loader.d.ts +2 -2
  218. package/react/src/providers/ContentProvider.d.ts +3 -3
  219. package/react/src/providers/ContentProvider.d.ts.map +1 -1
  220. package/react/src/providers/RerouteProvider.d.ts +8 -6
  221. package/react/src/providers/RerouteProvider.d.ts.map +1 -1
  222. package/react/src/providers/RouterProvider.d.ts +2 -2
  223. package/react/src/providers/index.d.ts +2 -2
  224. package/react/src/types/any.d.ts +2 -2
  225. package/react/src/types/index.d.ts +2 -2
  226. package/react/src/types/router.d.ts +2 -2
  227. package/telemetry/react.d.ts +2 -2
  228. package/telemetry/react.js +8 -4
  229. package/telemetry/react.js.map +2 -2
  230. package/telemetry/server.d.ts +2 -2
  231. package/telemetry/server.js +60 -5
  232. package/telemetry/server.js.map +22 -17
  233. package/telemetry/src/react/api.d.ts +2 -2
  234. package/telemetry/src/react/context.d.ts +2 -2
  235. package/telemetry/src/react/index.d.ts +2 -2
  236. package/telemetry/src/react/telemetry.d.ts +2 -2
  237. package/telemetry/src/server/context.d.ts +2 -2
  238. package/telemetry/src/server/headers/extractor.d.ts +2 -2
  239. package/telemetry/src/server/headers/index.d.ts +2 -2
  240. package/telemetry/src/server/headers/presets.d.ts +2 -2
  241. package/telemetry/src/server/index.d.ts +2 -2
  242. package/telemetry/src/server/instrumentation.d.ts +2 -2
  243. package/telemetry/src/server/plugin.d.ts +2 -2
  244. package/telemetry/src/server/sourcemap.d.ts +2 -2
package/react/index.js CHANGED
@@ -1,20 +1,24 @@
1
1
  /**
2
- * reroute-js v0.45.11
2
+ * reroute-js v0.46.0
3
3
  *
4
4
  * @license MIT
5
5
  * @copyright 2026 stewones <hi@stewan.io>
6
- * @see https://github.com/stewones/reroute
6
+ * @see https://github.com/Intenseloop/reroute
7
7
  *
8
8
  * Built with Bun <3
9
9
  */
10
10
  var __defProp = Object.defineProperty;
11
+ var __returnValue = (v) => v;
12
+ function __exportSetter(name, newValue) {
13
+ this[name] = __returnValue.bind(null, newValue);
14
+ }
11
15
  var __export = (target, all) => {
12
16
  for (var name in all)
13
17
  __defProp(target, name, {
14
18
  get: all[name],
15
19
  enumerable: true,
16
20
  configurable: true,
17
- set: (newValue) => all[name] = () => newValue
21
+ set: __exportSetter.bind(all, name)
18
22
  });
19
23
  };
20
24
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -393,32 +397,310 @@ import {
393
397
  isValidElement,
394
398
  useEffect as useEffect8,
395
399
  useLayoutEffect,
396
- useMemo as useMemo9,
400
+ useMemo as useMemo11,
397
401
  useRef,
398
402
  useState as useState8
399
403
  } from "react";
400
404
  import { flushSync as flushSync2 } from "react-dom";
401
405
 
402
406
  // packages/react/src/hooks/useContent.ts
403
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo3, useState as useState4 } from "react";
407
+ import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo4, useState as useState4 } from "react";
404
408
 
405
- // packages/react/src/providers/ContentProvider.tsx
409
+ // packages/react/src/i18n/helpers.ts
410
+ import { IntlMessageFormat } from "intl-messageformat";
411
+ function getMessage(catalog, key) {
412
+ if (!(catalog && key))
413
+ return;
414
+ const parts = key.split(".");
415
+ let current = catalog;
416
+ for (const part of parts) {
417
+ if (current == null || typeof current === "string")
418
+ return;
419
+ current = current[part];
420
+ }
421
+ return typeof current === "string" ? current : undefined;
422
+ }
423
+ function lookupMessage(catalogs, locale, defaultLocale, key) {
424
+ return getMessage(catalogs[locale], key) ?? (locale !== defaultLocale ? getMessage(catalogs[defaultLocale], key) : undefined);
425
+ }
426
+ var formatterCache = new Map;
427
+ function formatMessage(message, locale, values) {
428
+ if ((!values || Object.keys(values).length === 0) && !/\{[^}]+\}/.test(message)) {
429
+ return message;
430
+ }
431
+ const cacheKey = `${locale}\x00${message}`;
432
+ let formatter = formatterCache.get(cacheKey);
433
+ if (!formatter) {
434
+ formatter = new IntlMessageFormat(message, locale);
435
+ formatterCache.set(cacheKey, formatter);
436
+ }
437
+ try {
438
+ const result = formatter.format(values);
439
+ return typeof result === "string" ? result : String(result);
440
+ } catch {
441
+ return message;
442
+ }
443
+ }
444
+ function createTranslator(catalogs, locale, defaultLocale) {
445
+ return (key, values) => {
446
+ const message = lookupMessage(catalogs, locale, defaultLocale, key);
447
+ if (message == null)
448
+ return key;
449
+ return formatMessage(message, locale, values);
450
+ };
451
+ }
452
+ function looksLikeLocale(segment) {
453
+ return /^[a-z]{2}(?:-[A-Za-z0-9]{2,8})*$/i.test(segment);
454
+ }
455
+ function parseContentPath(pathname, availableLocales = [], collections) {
456
+ const pathOnly = pathname.split("?")[0].split("#")[0];
457
+ const parts = pathOnly.split("/").filter(Boolean);
458
+ if (parts.length < 2)
459
+ return;
460
+ const [collection, second, third] = parts;
461
+ if (collections && !collections.includes(collection)) {
462
+ return;
463
+ }
464
+ const localeSet = new Set(availableLocales.map((l) => l.toLowerCase()));
465
+ if (parts.length >= 3 && third) {
466
+ const secondIsLocale = localeSet.size > 0 ? localeSet.has(second.toLowerCase()) : looksLikeLocale(second);
467
+ if (secondIsLocale) {
468
+ const locale = availableLocales.find((l) => l.toLowerCase() === second.toLowerCase()) || second;
469
+ return {
470
+ collection,
471
+ name: third,
472
+ locale,
473
+ routingPathname: `/${collection}/${third}`
474
+ };
475
+ }
476
+ }
477
+ return {
478
+ collection,
479
+ name: second,
480
+ routingPathname: `/${collection}/${second}`
481
+ };
482
+ }
483
+ function localizeContentHref(collection, name, locale, defaultLocale) {
484
+ if (!locale || locale === defaultLocale) {
485
+ return `/${collection}/${name}`;
486
+ }
487
+ return `/${collection}/${locale}/${name}`;
488
+ }
489
+ function localizeHref(to, locale, defaultLocale, availableLocales = [], collections) {
490
+ try {
491
+ const url = new URL(to, "http://local");
492
+ const parsed = parseContentPath(url.pathname, availableLocales, collections);
493
+ if (!parsed)
494
+ return to;
495
+ url.pathname = localizeContentHref(parsed.collection, parsed.name, locale, defaultLocale);
496
+ return `${url.pathname}${url.search}${url.hash}`;
497
+ } catch {
498
+ return to;
499
+ }
500
+ }
501
+
502
+ // packages/react/src/i18n/LocaleProvider.tsx
406
503
  import {
407
504
  createContext,
408
505
  useCallback,
409
506
  useContext,
410
507
  useMemo,
508
+ useSyncExternalStore
509
+ } from "react";
510
+ import { jsx as jsx2 } from "react/jsx-runtime";
511
+ var LocaleContext = createContext(null);
512
+ var DISABLED_STATE = {
513
+ enabled: false,
514
+ locale: "en-US",
515
+ defaultLocale: "en-US",
516
+ locales: [],
517
+ cookie: "reroute-locale",
518
+ catalogs: {}
519
+ };
520
+ function readHydration() {
521
+ try {
522
+ const g = globalThis;
523
+ const raw = g.__REROUTE_I18N__;
524
+ if (raw && typeof raw === "object") {
525
+ return {
526
+ enabled: !!raw.enabled,
527
+ locale: raw.locale || "en-US",
528
+ defaultLocale: raw.defaultLocale || "en-US",
529
+ locales: Array.isArray(raw.locales) ? raw.locales : [],
530
+ cookie: raw.cookie || "reroute-locale",
531
+ catalogs: raw.catalogs || {},
532
+ collections: raw.collections
533
+ };
534
+ }
535
+ } catch {}
536
+ return DISABLED_STATE;
537
+ }
538
+ function sameHydration(a, b) {
539
+ return a.enabled === b.enabled && a.locale === b.locale && a.defaultLocale === b.defaultLocale && a.cookie === b.cookie && a.catalogs === b.catalogs && a.locales === b.locales && a.collections === b.collections;
540
+ }
541
+ var store = {
542
+ state: readHydration(),
543
+ listeners: new Set
544
+ };
545
+ function subscribe(listener) {
546
+ store.listeners.add(listener);
547
+ return () => {
548
+ store.listeners.delete(listener);
549
+ };
550
+ }
551
+ function getSnapshot() {
552
+ const fromGlobal = readHydration();
553
+ if (fromGlobal.enabled && !sameHydration(store.state, fromGlobal)) {
554
+ store.state = fromGlobal;
555
+ }
556
+ return store.state;
557
+ }
558
+ function getServerSnapshot() {
559
+ return store.state;
560
+ }
561
+ function setStoreState(partial) {
562
+ const next = { ...store.state, ...partial };
563
+ if (sameHydration(store.state, next))
564
+ return;
565
+ store.state = next;
566
+ try {
567
+ globalThis.__REROUTE_I18N__ = store.state;
568
+ } catch {}
569
+ for (const listener of store.listeners)
570
+ listener();
571
+ }
572
+ function seedStore(value) {
573
+ const next = {
574
+ ...readHydration(),
575
+ ...value,
576
+ enabled: true,
577
+ locale: value.locale || store.state.locale,
578
+ defaultLocale: value.defaultLocale || store.state.defaultLocale,
579
+ locales: value.locales || store.state.locales,
580
+ cookie: value.cookie || store.state.cookie,
581
+ catalogs: value.catalogs || store.state.catalogs,
582
+ collections: value.collections || store.state.collections
583
+ };
584
+ if (sameHydration(store.state, next))
585
+ return;
586
+ store.state = next;
587
+ try {
588
+ globalThis.__REROUTE_I18N__ = store.state;
589
+ } catch {}
590
+ }
591
+ function writeLocaleCookie(name, locale) {
592
+ if (typeof document === "undefined")
593
+ return;
594
+ const maxAge = 60 * 60 * 24 * 365;
595
+ document.cookie = `${name}=${encodeURIComponent(locale)}; Path=/; Max-Age=${maxAge}; SameSite=Lax`;
596
+ }
597
+ function LocaleProvider({
598
+ children,
599
+ value
600
+ }) {
601
+ if (value?.enabled) {
602
+ seedStore(value);
603
+ }
604
+ const state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
605
+ const translator = useMemo(() => {
606
+ if (!state.enabled) {
607
+ return (key) => key;
608
+ }
609
+ return createTranslator(state.catalogs, state.locale, state.defaultLocale);
610
+ }, [state.enabled, state.catalogs, state.locale, state.defaultLocale]);
611
+ const setLocale = useCallback((next) => {
612
+ if (!state.enabled)
613
+ return;
614
+ if (!state.locales.includes(next))
615
+ return;
616
+ writeLocaleCookie(state.cookie, next);
617
+ setStoreState({ locale: next });
618
+ if (typeof window === "undefined")
619
+ return;
620
+ const parsed = parseContentPath(window.location.pathname, state.locales, state.collections);
621
+ if (parsed) {
622
+ const target = localizeContentHref(parsed.collection, parsed.name, next, state.defaultLocale);
623
+ const url = `${target}${window.location.search}${window.location.hash}`;
624
+ window.location.assign(url);
625
+ return;
626
+ }
627
+ window.location.reload();
628
+ }, [state]);
629
+ const localizePath = useCallback((to) => {
630
+ if (!state.enabled)
631
+ return to;
632
+ return localizeHref(to, state.locale, state.defaultLocale, state.locales, state.collections);
633
+ }, [state]);
634
+ const localizeContentPath = useCallback((collection, name) => {
635
+ if (!state.enabled)
636
+ return `/${collection}/${name}`;
637
+ return localizeContentHref(collection, name, state.locale, state.defaultLocale);
638
+ }, [state]);
639
+ const ctx = useMemo(() => ({
640
+ enabled: state.enabled,
641
+ locale: state.locale,
642
+ defaultLocale: state.defaultLocale,
643
+ locales: state.locales,
644
+ t: translator,
645
+ setLocale,
646
+ localizePath,
647
+ localizeContentPath
648
+ }), [state, translator, setLocale, localizePath, localizeContentPath]);
649
+ return /* @__PURE__ */ jsx2(LocaleContext.Provider, {
650
+ value: ctx,
651
+ children
652
+ });
653
+ }
654
+ function useLocaleContext() {
655
+ const ctx = useContext(LocaleContext);
656
+ if (ctx)
657
+ return ctx;
658
+ return {
659
+ enabled: false,
660
+ locale: "en-US",
661
+ defaultLocale: "en-US",
662
+ locales: [],
663
+ t: (key) => key,
664
+ setLocale: () => {},
665
+ localizePath: (to) => to,
666
+ localizeContentPath: (collection, name) => `/${collection}/${name}`
667
+ };
668
+ }
669
+ function useLocale() {
670
+ const { locale, locales, defaultLocale, enabled, setLocale } = useLocaleContext();
671
+ return { locale, locales, defaultLocale, enabled, setLocale };
672
+ }
673
+ function t(key, values) {
674
+ const state = getSnapshot();
675
+ if (!state.enabled)
676
+ return key;
677
+ return createTranslator(state.catalogs, state.locale, state.defaultLocale)(key, values);
678
+ }
679
+
680
+ // packages/react/src/providers/ContentProvider.tsx
681
+ import {
682
+ createContext as createContext2,
683
+ useCallback as useCallback2,
684
+ useContext as useContext2,
685
+ useMemo as useMemo2,
411
686
  useState as useState2
412
687
  } from "react";
413
688
 
414
689
  // packages/react/src/lib/content.ts
690
+ function looksLikeLocale2(segment) {
691
+ return /^[a-z]{2}(?:-[A-Za-z0-9]{2,8})*$/i.test(segment);
692
+ }
415
693
  function parseContentHref(href) {
416
694
  try {
417
695
  const url = new URL(href, "http://local");
418
- const [collection, name] = url.pathname.split("/").filter(Boolean);
419
- if (!(collection && name))
696
+ const parts = url.pathname.split("/").filter(Boolean);
697
+ if (parts.length < 2)
420
698
  return;
421
- return { collection, name };
699
+ const [collection, second, third] = parts;
700
+ if (parts.length >= 3 && third && looksLikeLocale2(second)) {
701
+ return { collection, name: third, locale: second };
702
+ }
703
+ return { collection, name: second };
422
704
  } catch {
423
705
  return;
424
706
  }
@@ -429,7 +711,7 @@ function createResolverFromGetEntry(getEntry) {
429
711
  if (!parsed)
430
712
  return;
431
713
  try {
432
- const entry = getEntry(parsed.collection, parsed.name);
714
+ const entry = getEntry(parsed.collection, parsed.name, parsed.locale);
433
715
  if (!entry)
434
716
  return parsed;
435
717
  const moduleUrl = entry?.module;
@@ -441,12 +723,33 @@ function createResolverFromGetEntry(getEntry) {
441
723
  }
442
724
 
443
725
  // packages/react/src/providers/ContentProvider.tsx
444
- import { jsx as jsx2 } from "react/jsx-runtime";
445
- var ContentRegistryContext = createContext(null);
446
- var ContentIndexContext = createContext(null);
447
- var ContentGetEntryContext = createContext(null);
448
- var ContentLoadCollectionContext = createContext(null);
449
- var MarkdownComponentsContext = createContext(null);
726
+ import { jsx as jsx3 } from "react/jsx-runtime";
727
+ function findIndexEntry(list, name, locale) {
728
+ if (locale) {
729
+ return list.find((e) => e?.name === name && e?.locale === locale) || list.find((e) => e?.name === name);
730
+ }
731
+ return list.find((e) => e?.name === name);
732
+ }
733
+ function resolveFromIndex(href, idx) {
734
+ const parsed = parseContentHref(href);
735
+ if (!parsed)
736
+ return;
737
+ try {
738
+ const list = idx[parsed.collection];
739
+ if (Array.isArray(list)) {
740
+ const found = findIndexEntry(list, parsed.name, parsed.locale);
741
+ if (found && typeof found.module === "string") {
742
+ return { ...parsed, module: found.module };
743
+ }
744
+ }
745
+ } catch {}
746
+ return parsed;
747
+ }
748
+ var ContentRegistryContext = createContext2(null);
749
+ var ContentIndexContext = createContext2(null);
750
+ var ContentGetEntryContext = createContext2(null);
751
+ var ContentLoadCollectionContext = createContext2(null);
752
+ var MarkdownComponentsContext = createContext2(null);
450
753
  function ContentProvider({
451
754
  children,
452
755
  resolveByHref,
@@ -482,28 +785,14 @@ function ContentProvider({
482
785
  return result;
483
786
  });
484
787
  const entryFn = getEntry || null;
485
- const resolver = useMemo(() => {
788
+ const resolver = useMemo2(() => {
486
789
  if (typeof resolveByHref === "function")
487
790
  return resolveByHref;
488
791
  if (typeof getEntry === "function")
489
792
  return createResolverFromGetEntry(getEntry);
490
- return (href) => {
491
- const parsed = parseContentHref(href);
492
- if (!parsed)
493
- return;
494
- try {
495
- const list = idx?.[parsed.collection];
496
- if (Array.isArray(list)) {
497
- const found = list.find((e) => e?.name === parsed.name);
498
- if (found && typeof found.module === "string") {
499
- return { ...parsed, module: found.module };
500
- }
501
- }
502
- } catch {}
503
- return parsed;
504
- };
793
+ return (href) => resolveFromIndex(href, idx);
505
794
  }, [resolveByHref, getEntry, idx]);
506
- const ensureCollection = useCallback(async (collection) => {
795
+ const ensureCollection = useCallback2(async (collection) => {
507
796
  try {
508
797
  const existing = idx[collection];
509
798
  const w = typeof window !== "undefined" ? window : undefined;
@@ -527,15 +816,15 @@ function ContentProvider({
527
816
  return;
528
817
  }
529
818
  }, [idx, loadCollection]);
530
- return /* @__PURE__ */ jsx2(ContentRegistryContext.Provider, {
819
+ return /* @__PURE__ */ jsx3(ContentRegistryContext.Provider, {
531
820
  value: resolver,
532
- children: /* @__PURE__ */ jsx2(ContentIndexContext.Provider, {
821
+ children: /* @__PURE__ */ jsx3(ContentIndexContext.Provider, {
533
822
  value: idx,
534
- children: /* @__PURE__ */ jsx2(ContentGetEntryContext.Provider, {
823
+ children: /* @__PURE__ */ jsx3(ContentGetEntryContext.Provider, {
535
824
  value: entryFn,
536
- children: /* @__PURE__ */ jsx2(ContentLoadCollectionContext.Provider, {
825
+ children: /* @__PURE__ */ jsx3(ContentLoadCollectionContext.Provider, {
537
826
  value: ensureCollection,
538
- children: /* @__PURE__ */ jsx2(MarkdownComponentsContext.Provider, {
827
+ children: /* @__PURE__ */ jsx3(MarkdownComponentsContext.Provider, {
539
828
  value: markdownComponents || null,
540
829
  children
541
830
  })
@@ -545,23 +834,23 @@ function ContentProvider({
545
834
  });
546
835
  }
547
836
  function useContentResolver() {
548
- return useContext(ContentRegistryContext);
837
+ return useContext2(ContentRegistryContext);
549
838
  }
550
839
  function useContentIndex() {
551
- return useContext(ContentIndexContext);
840
+ return useContext2(ContentIndexContext);
552
841
  }
553
842
  function useContentGetEntry() {
554
- return useContext(ContentGetEntryContext);
843
+ return useContext2(ContentGetEntryContext);
555
844
  }
556
845
  function useContentLoadCollection() {
557
- return useContext(ContentLoadCollectionContext);
846
+ return useContext2(ContentLoadCollectionContext);
558
847
  }
559
848
  function useMarkdownComponents() {
560
- return useContext(MarkdownComponentsContext);
849
+ return useContext2(MarkdownComponentsContext);
561
850
  }
562
851
 
563
852
  // packages/react/src/hooks/useSearch.ts
564
- import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useState as useState3 } from "react";
853
+ import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useState as useState3 } from "react";
565
854
  function useSearch(params) {
566
855
  const {
567
856
  query,
@@ -571,7 +860,7 @@ function useSearch(params) {
571
860
  enabled = true,
572
861
  debounce = 300
573
862
  } = params;
574
- const stableCollections = useMemo2(() => collections, [collections]);
863
+ const stableCollections = useMemo3(() => collections, [collections]);
575
864
  const [results, setResults] = useState3([]);
576
865
  const [total, setTotal] = useState3(0);
577
866
  const [page, setPage] = useState3(paramPage);
@@ -579,7 +868,7 @@ function useSearch(params) {
579
868
  const [totalPages, setTotalPages] = useState3(0);
580
869
  const [isLoading, setIsLoading] = useState3(false);
581
870
  const [error, setError] = useState3(null);
582
- const performSearch = useCallback2(async (searchQuery, searchPage) => {
871
+ const performSearch = useCallback3(async (searchQuery, searchPage) => {
583
872
  if (!searchQuery.trim()) {
584
873
  setResults([]);
585
874
  setTotal(0);
@@ -603,6 +892,12 @@ function useSearch(params) {
603
892
  if (paramPageSize) {
604
893
  params2.set("pageSize", String(paramPageSize));
605
894
  }
895
+ try {
896
+ const g = globalThis;
897
+ if (g.__REROUTE_I18N__?.enabled && g.__REROUTE_I18N__.locale) {
898
+ params2.set("lang", g.__REROUTE_I18N__.locale);
899
+ }
900
+ } catch {}
606
901
  const response = await fetch(`/__reroute_search?${params2.toString()}`);
607
902
  if (!response.ok) {
608
903
  const errorData = await response.json().catch(() => ({}));
@@ -647,7 +942,7 @@ function useSearch(params) {
647
942
  }, debounce);
648
943
  return () => clearTimeout(timeoutId);
649
944
  }, [query, paramPage, enabled, debounce, performSearch]);
650
- const search = useCallback2(async (newQuery, newPage) => {
945
+ const search = useCallback3(async (newQuery, newPage) => {
651
946
  await performSearch(newQuery, newPage);
652
947
  }, [performSearch]);
653
948
  return {
@@ -663,6 +958,24 @@ function useSearch(params) {
663
958
  }
664
959
 
665
960
  // packages/react/src/hooks/useContent.ts
961
+ function pickLocaleEntries(list, locale, defaultLocale) {
962
+ const byName = new Map;
963
+ for (const item of list) {
964
+ const name = item.name;
965
+ if (!name)
966
+ continue;
967
+ const arr = byName.get(name) || [];
968
+ arr.push(item);
969
+ byName.set(name, arr);
970
+ }
971
+ const result = [];
972
+ for (const variants of byName.values()) {
973
+ const preferred = variants.find((v) => v.locale === locale) || variants.find((v) => v.locale === defaultLocale) || variants.find((v) => !v.locale) || variants[0];
974
+ if (preferred)
975
+ result.push(preferred);
976
+ }
977
+ return result;
978
+ }
666
979
  function sortByDate(order) {
667
980
  return (a, b) => {
668
981
  const da = a?.meta && a.meta?.date ? Date.parse(String(a.meta.date)) : 0;
@@ -825,11 +1138,11 @@ function prefetchContent(entry) {
825
1138
  const w = window;
826
1139
  if (!w.__REROUTE_MODULES__)
827
1140
  w.__REROUTE_MODULES__ = {};
828
- const store = w.__REROUTE_MODULES__;
829
- if (store[key])
1141
+ const store2 = w.__REROUTE_MODULES__;
1142
+ if (store2[key])
830
1143
  return;
831
1144
  import(modUrl).then((m) => {
832
- store[key] = m;
1145
+ store2[key] = m;
833
1146
  }).catch(() => {});
834
1147
  } catch {}
835
1148
  }
@@ -870,6 +1183,7 @@ function useContent(params) {
870
1183
  }
871
1184
  const index = useContentIndex();
872
1185
  const loadCollection = useContentLoadCollection();
1186
+ const { locale, defaultLocale, enabled: i18nEnabled } = useLocale();
873
1187
  const [_ready, setReady] = useState4(() => {
874
1188
  const have = index?.[collection];
875
1189
  return Array.isArray(have) && have.length > 0;
@@ -931,12 +1245,19 @@ function useContent(params) {
931
1245
  cancelled = true;
932
1246
  };
933
1247
  }, [collection, index, loadCollection, limit, filter, fields]);
934
- const items = useMemo3(() => {
1248
+ const items = useMemo4(() => {
935
1249
  const source = index || {};
936
1250
  const list = source?.[collection];
937
1251
  if (!Array.isArray(list) || list.length === 0)
938
1252
  return [];
939
1253
  let cloned = [...list];
1254
+ if (i18nEnabled) {
1255
+ cloned = pickLocaleEntries(cloned, locale, defaultLocale);
1256
+ cloned = cloned.map((item) => ({
1257
+ ...item,
1258
+ href: localizeContentHref(item.collection || collection, item.name, locale, defaultLocale)
1259
+ }));
1260
+ }
940
1261
  cloned = applyFilter(cloned, filter);
941
1262
  if (typeof sort === "function") {
942
1263
  cloned = cloned.sort(sort);
@@ -970,14 +1291,23 @@ function useContent(params) {
970
1291
  } catch {}
971
1292
  }
972
1293
  return cloned;
973
- }, [index, collection, sort, limit, filter]);
1294
+ }, [
1295
+ index,
1296
+ collection,
1297
+ sort,
1298
+ limit,
1299
+ filter,
1300
+ i18nEnabled,
1301
+ locale,
1302
+ defaultLocale
1303
+ ]);
974
1304
  useEffect3(() => {
975
1305
  if (typeof window === "undefined")
976
1306
  return;
977
1307
  const handler = (e) => {
978
1308
  const detail = e.detail;
979
1309
  if (detail?.collection === collection) {
980
- setContentLoadTick((t) => t + 1);
1310
+ setContentLoadTick((t2) => t2 + 1);
981
1311
  }
982
1312
  };
983
1313
  window.addEventListener("__reroute_content_loading__", handler);
@@ -987,8 +1317,8 @@ function useContent(params) {
987
1317
  window.removeEventListener("__reroute_content_loaded__", handler);
988
1318
  };
989
1319
  }, [collection]);
990
- const prefetch = useCallback3((entry) => prefetchContent(entry), []);
991
- const hasLoadingModules = useMemo3(() => {
1320
+ const prefetch = useCallback4((entry) => prefetchContent(entry), []);
1321
+ const hasLoadingModules = useMemo4(() => {
992
1322
  if (typeof window === "undefined") {
993
1323
  return false;
994
1324
  }
@@ -1005,17 +1335,20 @@ function useContent(params) {
1005
1335
  return { items, isLoading, prefetch };
1006
1336
  }
1007
1337
  // packages/react/src/hooks/useData.ts
1008
- import { useEffect as useEffect5, useMemo as useMemo5, useState as useState5 } from "react";
1338
+ import { useEffect as useEffect5, useMemo as useMemo7, useState as useState5 } from "react";
1009
1339
 
1010
1340
  // packages/react/src/hooks/useRouter.tsx
1011
- import { useContext as useContext2 } from "react";
1341
+ import { useContext as useContext3 } from "react";
1342
+ // packages/react/src/providers/RerouteProvider.tsx
1343
+ import { useCallback as useCallback6, useMemo as useMemo6 } from "react";
1344
+
1012
1345
  // packages/react/src/providers/RouterProvider.tsx
1013
1346
  import React, {
1014
- createContext as createContext2,
1015
- useCallback as useCallback4,
1347
+ createContext as createContext3,
1348
+ useCallback as useCallback5,
1016
1349
  useEffect as useEffect4,
1017
- useMemo as useMemo4,
1018
- useSyncExternalStore
1350
+ useMemo as useMemo5,
1351
+ useSyncExternalStore as useSyncExternalStore2
1019
1352
  } from "react";
1020
1353
  import { flushSync } from "react-dom";
1021
1354
 
@@ -1163,10 +1496,10 @@ function applyRouteHead(head) {
1163
1496
  }
1164
1497
 
1165
1498
  // packages/react/src/providers/RouterProvider.tsx
1166
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1499
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1167
1500
  var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "undefined";
1168
- var OutletContext = createContext2(null);
1169
- var RouterContext = createContext2(null);
1501
+ var OutletContext = createContext3(null);
1502
+ var RouterContext = createContext3(null);
1170
1503
  var listeners = [];
1171
1504
  var currentLocation = isBrowser2 ? {
1172
1505
  pathname: window.location.pathname,
@@ -1208,7 +1541,7 @@ function applyHeadIfStillOnPage(pathnameToUse, payload, matchRoute) {
1208
1541
  console.error("[RouterProvider] Error applying head after lazy fetch:", e);
1209
1542
  }
1210
1543
  }
1211
- } else {}
1544
+ }
1212
1545
  });
1213
1546
  }
1214
1547
  function processLazyFetchResponse(json, pathnameToUse, matchRoute) {
@@ -1289,7 +1622,7 @@ function applyRouteHeadAndLang(currentPathname, pathname, target, matchRoute) {
1289
1622
  applyLang(ssr.lang);
1290
1623
  } catch {}
1291
1624
  }
1292
- function subscribe(listener) {
1625
+ function subscribe2(listener) {
1293
1626
  if (!isBrowser2)
1294
1627
  return () => {};
1295
1628
  listeners.push(listener);
@@ -1297,7 +1630,7 @@ function subscribe(listener) {
1297
1630
  listeners = listeners.filter((l) => l !== listener);
1298
1631
  };
1299
1632
  }
1300
- function getSnapshot() {
1633
+ function getSnapshot2() {
1301
1634
  return currentLocation;
1302
1635
  }
1303
1636
  function emitChange() {
@@ -1457,8 +1790,8 @@ function RouterProvider({
1457
1790
  serverSnapshotRef.current = { pathname: pathOnly, search, hash };
1458
1791
  }
1459
1792
  }
1460
- const getServerSnapshot = useCallback4(() => serverSnapshotRef.current, []);
1461
- const location = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) || currentLocation;
1793
+ const getServerSnapshot2 = useCallback5(() => serverSnapshotRef.current, []);
1794
+ const location = useSyncExternalStore2(subscribe2, getSnapshot2, getServerSnapshot2) || currentLocation;
1462
1795
  useEffect4(() => {
1463
1796
  if (!isBrowser2)
1464
1797
  return;
@@ -1472,10 +1805,10 @@ function RouterProvider({
1472
1805
  emitChange();
1473
1806
  }
1474
1807
  }, []);
1475
- const target = useMemo4(() => matchRoute(location.pathname), [location.pathname, matchRoute]);
1808
+ const target = useMemo5(() => matchRoute(location.pathname), [location.pathname, matchRoute]);
1476
1809
  const params = target?.params || {};
1477
- const searchParams = useMemo4(() => new URLSearchParams(location.search), [location.search]);
1478
- const navigate = useCallback4((to, options = {}) => {
1810
+ const searchParams = useMemo5(() => new URLSearchParams(location.search), [location.search]);
1811
+ const navigate = useCallback5((to, options = {}) => {
1479
1812
  navigateInternal(to, options);
1480
1813
  }, []);
1481
1814
  useEffect4(() => {
@@ -1652,7 +1985,7 @@ function RouterProvider({
1652
1985
  }
1653
1986
  };
1654
1987
  }, [target, pathname, matchRoute]);
1655
- const notFoundResolver = useCallback4((pathname2) => {
1988
+ const notFoundResolver = useCallback5((pathname2) => {
1656
1989
  try {
1657
1990
  const list = Array.isArray(notFoundRoutes) ? notFoundRoutes : [];
1658
1991
  let chosen;
@@ -1672,7 +2005,7 @@ function RouterProvider({
1672
2005
  return;
1673
2006
  }
1674
2007
  }, [notFoundRoutes]);
1675
- const contextValue = useMemo4(() => ({
2008
+ const contextValue = useMemo5(() => ({
1676
2009
  pathname: location.pathname,
1677
2010
  params,
1678
2011
  searchParams,
@@ -1689,7 +2022,7 @@ function RouterProvider({
1689
2022
  matchRoute,
1690
2023
  notFoundResolver
1691
2024
  ]);
1692
- const matchingLayouts = useMemo4(() => {
2025
+ const matchingLayouts = useMemo5(() => {
1693
2026
  return layouts.filter((layout) => {
1694
2027
  if (layout.pattern === "/")
1695
2028
  return true;
@@ -1701,25 +2034,25 @@ function RouterProvider({
1701
2034
  let content;
1702
2035
  if (target) {
1703
2036
  const Component = target.route.component;
1704
- let outletContent = /* @__PURE__ */ jsx3(Component, {});
2037
+ let outletContent = /* @__PURE__ */ jsx4(Component, {});
1705
2038
  for (let i = matchingLayouts.length - 1;i >= 0; i--) {
1706
2039
  const Layout = matchingLayouts[i].component;
1707
2040
  const currentOutlet = outletContent;
1708
- outletContent = /* @__PURE__ */ jsx3(OutletContext.Provider, {
2041
+ outletContent = /* @__PURE__ */ jsx4(OutletContext.Provider, {
1709
2042
  value: currentOutlet,
1710
- children: /* @__PURE__ */ jsx3(Layout, {})
2043
+ children: /* @__PURE__ */ jsx4(Layout, {})
1711
2044
  });
1712
2045
  }
1713
2046
  content = outletContent;
1714
2047
  } else {
1715
2048
  const Fallback = notFoundResolver(location.pathname) || NotFound;
1716
2049
  if (Fallback) {
1717
- content = /* @__PURE__ */ jsx3(Fallback, {});
2050
+ content = /* @__PURE__ */ jsx4(Fallback, {});
1718
2051
  } else {
1719
2052
  content = /* @__PURE__ */ jsxs("div", {
1720
2053
  style: { padding: "2rem", textAlign: "center" },
1721
2054
  children: [
1722
- /* @__PURE__ */ jsx3("h1", {
2055
+ /* @__PURE__ */ jsx4("h1", {
1723
2056
  children: "404 - Page Not Found"
1724
2057
  }),
1725
2058
  /* @__PURE__ */ jsxs("p", {
@@ -1729,7 +2062,7 @@ function RouterProvider({
1729
2062
  " could not be found."
1730
2063
  ]
1731
2064
  }),
1732
- /* @__PURE__ */ jsx3("a", {
2065
+ /* @__PURE__ */ jsx4("a", {
1733
2066
  href: "/",
1734
2067
  children: "Go Home"
1735
2068
  })
@@ -1737,14 +2070,22 @@ function RouterProvider({
1737
2070
  });
1738
2071
  }
1739
2072
  }
1740
- return /* @__PURE__ */ jsx3(RouterContext.Provider, {
2073
+ return /* @__PURE__ */ jsx4(RouterContext.Provider, {
1741
2074
  value: contextValue,
1742
2075
  children: children || content
1743
2076
  });
1744
2077
  }
1745
2078
 
1746
2079
  // packages/react/src/providers/RerouteProvider.tsx
1747
- import { jsx as jsx4 } from "react/jsx-runtime";
2080
+ import { jsx as jsx5 } from "react/jsx-runtime";
2081
+ function readI18nHydration() {
2082
+ try {
2083
+ const raw = globalThis.__REROUTE_I18N__;
2084
+ if (raw?.enabled)
2085
+ return raw;
2086
+ } catch {}
2087
+ return;
2088
+ }
1748
2089
  function RerouteProvider({
1749
2090
  byCollection,
1750
2091
  getContentEntry,
@@ -1759,30 +2100,51 @@ function RerouteProvider({
1759
2100
  viewTransitions,
1760
2101
  scrollRestoration,
1761
2102
  markdownComponents,
2103
+ i18n: i18nProp,
1762
2104
  children
1763
2105
  }) {
1764
2106
  const loader = loadContent || (contentBaseUrl ? (c) => import(`${contentBaseUrl}/${c}.js`) : undefined);
1765
- return /* @__PURE__ */ jsx4(ContentProvider, {
1766
- getEntry: getContentEntry,
1767
- byCollection: byCollection || null,
1768
- loadCollection: loader,
1769
- markdownComponents,
1770
- children: /* @__PURE__ */ jsx4(RouterProvider, {
1771
- layouts,
1772
- matchRoute,
1773
- notFoundRoutes,
1774
- notFound,
1775
- pathname,
1776
- searchParams,
1777
- viewTransitions,
1778
- scrollRestoration,
1779
- children
2107
+ const i18n = i18nProp?.enabled ? i18nProp : readI18nHydration();
2108
+ const locales = i18n?.locales || [];
2109
+ const collections = useMemo6(() => {
2110
+ if (i18n?.collections?.length)
2111
+ return i18n.collections;
2112
+ if (byCollection)
2113
+ return Object.keys(byCollection);
2114
+ return;
2115
+ }, [i18n?.collections, byCollection]);
2116
+ const matchRouteWithLocale = useCallback6((path) => {
2117
+ if (!(i18n?.enabled && locales.length)) {
2118
+ return matchRoute(path);
2119
+ }
2120
+ const parsed = parseContentPath(path, locales, collections);
2121
+ const routingPath = parsed?.routingPathname || path;
2122
+ return matchRoute(routingPath);
2123
+ }, [i18n?.enabled, locales, collections, matchRoute]);
2124
+ return /* @__PURE__ */ jsx5(LocaleProvider, {
2125
+ value: i18n,
2126
+ children: /* @__PURE__ */ jsx5(ContentProvider, {
2127
+ getEntry: getContentEntry,
2128
+ byCollection: byCollection || null,
2129
+ loadCollection: loader,
2130
+ markdownComponents,
2131
+ children: /* @__PURE__ */ jsx5(RouterProvider, {
2132
+ layouts,
2133
+ matchRoute: matchRouteWithLocale,
2134
+ notFoundRoutes,
2135
+ notFound,
2136
+ pathname,
2137
+ searchParams,
2138
+ viewTransitions,
2139
+ scrollRestoration,
2140
+ children
2141
+ })
1780
2142
  })
1781
2143
  });
1782
2144
  }
1783
2145
  // packages/react/src/hooks/useRouter.tsx
1784
2146
  function useRouter() {
1785
- const context = useContext2(RouterContext);
2147
+ const context = useContext3(RouterContext);
1786
2148
  if (!context) {
1787
2149
  throw new Error("useRouter must be used within a RouterProvider");
1788
2150
  }
@@ -2003,7 +2365,7 @@ function useData(key) {
2003
2365
  pending[pathToFetch] = fetchPromise;
2004
2366
  } catch {}
2005
2367
  }, [k, pathname]);
2006
- return useMemo5(() => {
2368
+ return useMemo7(() => {
2007
2369
  try {
2008
2370
  const source = typeof window === "undefined" ? globalThis.__REROUTE_DATA__ : window.__REROUTE_DATA__;
2009
2371
  let value = source?.[k];
@@ -2168,10 +2530,10 @@ function useData(key) {
2168
2530
  }, [k, _tick, pathname]);
2169
2531
  }
2170
2532
  // packages/react/src/hooks/useFeed.ts
2171
- import { useMemo as useMemo6 } from "react";
2533
+ import { useMemo as useMemo8 } from "react";
2172
2534
  function useFeed() {
2173
2535
  const { pathname } = useRouter();
2174
- return useMemo6(() => {
2536
+ return useMemo8(() => {
2175
2537
  const availableFeeds = typeof globalThis !== "undefined" ? globalThis.__REROUTE_AVAILABLE_FEEDS__ || globalThis.__REROUTE_FEEDS__ || [] : [];
2176
2538
  const parts = pathname.split("/").filter(Boolean);
2177
2539
  const mainFeedUrl = "/feed.xml";
@@ -2199,7 +2561,7 @@ function useFeed() {
2199
2561
  }, [pathname]);
2200
2562
  }
2201
2563
  // packages/react/src/hooks/useLayoutData.ts
2202
- import { useEffect as useEffect6, useMemo as useMemo7, useState as useState6 } from "react";
2564
+ import { useEffect as useEffect6, useMemo as useMemo9, useState as useState6 } from "react";
2203
2565
  var isThenable2 = (value) => {
2204
2566
  return typeof value === "object" && value !== null && typeof value.then === "function";
2205
2567
  };
@@ -2214,7 +2576,7 @@ var isInitialHydration2 = () => {
2214
2576
  function useLayoutData() {
2215
2577
  const { pathname } = useRouter();
2216
2578
  const [_tick, setTick] = useState6(0);
2217
- const layoutKey = useMemo7(() => {
2579
+ const layoutKey = useMemo9(() => {
2218
2580
  const parts = pathname.split("/").filter(Boolean);
2219
2581
  if (parts.length === 0)
2220
2582
  return "__layout:/";
@@ -2303,7 +2665,7 @@ function useLayoutData() {
2303
2665
  });
2304
2666
  } catch {}
2305
2667
  }, [layoutKey, pathname]);
2306
- return useMemo7(() => {
2668
+ return useMemo9(() => {
2307
2669
  try {
2308
2670
  const source = typeof window === "undefined" ? globalThis.__REROUTE_DATA__ : window.__REROUTE_DATA__;
2309
2671
  let value = source?.[layoutKey];
@@ -2361,10 +2723,10 @@ function useLayoutData() {
2361
2723
  }, [layoutKey, _tick]);
2362
2724
  }
2363
2725
  // packages/react/src/hooks/useLlms.ts
2364
- import { useMemo as useMemo8 } from "react";
2726
+ import { useMemo as useMemo10 } from "react";
2365
2727
  function useLlms() {
2366
2728
  const { pathname } = useRouter();
2367
- return useMemo8(() => {
2729
+ return useMemo10(() => {
2368
2730
  const availableLlms = typeof globalThis !== "undefined" ? globalThis.__REROUTE_AVAILABLE_LLMS__ || globalThis.__REROUTE_LLMS__ || [] : [];
2369
2731
  const parts = pathname.split("/").filter(Boolean);
2370
2732
  const mainLlmsUrl = "/llms.txt";
@@ -2488,7 +2850,16 @@ function useToc() {
2488
2850
  return { toc, isLoading: false };
2489
2851
  }
2490
2852
  // packages/react/src/components/ContentRoute.tsx
2491
- import { jsx as jsx5 } from "react/jsx-runtime";
2853
+ import { jsx as jsx6 } from "react/jsx-runtime";
2854
+ function looksLikeLocale3(segment) {
2855
+ return /^[a-z]{2}(?:-[A-Za-z0-9]{2,8})*$/i.test(segment);
2856
+ }
2857
+ function contentModuleKey(collection, name, locale, defaultLocale) {
2858
+ if (locale && locale !== defaultLocale) {
2859
+ return `${collection}:${name}:${locale}`;
2860
+ }
2861
+ return `${collection}:${name}`;
2862
+ }
2492
2863
  function getCapturedHtml(key) {
2493
2864
  try {
2494
2865
  const g = globalThis;
@@ -2512,26 +2883,33 @@ function ContentRoute({
2512
2883
  const params = useParams();
2513
2884
  const router = useRouter();
2514
2885
  const { pathname, notFoundResolver } = router;
2515
- const inferredName = name || params.slug || params.name || (() => {
2886
+ const { locale, defaultLocale, enabled: i18nEnabled } = useLocale();
2887
+ const pathInfo = (() => {
2516
2888
  try {
2517
2889
  const parts = String(pathname || "").split("/").filter(Boolean);
2518
- return parts.length >= 2 ? parts[1] : undefined;
2519
- } catch {
2520
- return;
2521
- }
2890
+ if (parts.length >= 3 && looksLikeLocale3(parts[1])) {
2891
+ return { name: parts[2], locale: parts[1] };
2892
+ }
2893
+ if (parts.length >= 2) {
2894
+ return { name: parts[1], locale: undefined };
2895
+ }
2896
+ } catch {}
2897
+ return { name: undefined, locale: undefined };
2522
2898
  })();
2523
- const key = inferredName ? `${collection}:${inferredName}` : `${collection}:`;
2899
+ const inferredName = name || params.slug || params.name || pathInfo.name;
2900
+ const activeLocale = pathInfo.locale || (i18nEnabled ? locale : defaultLocale) || defaultLocale;
2901
+ const key = inferredName ? contentModuleKey(collection, inferredName, activeLocale, defaultLocale) : `${collection}:`;
2524
2902
  const ctxGetEntry = useContentGetEntry();
2525
2903
  const idx = useContentIndex();
2526
2904
  const ensureCollection = useContentLoadCollection();
2527
2905
  const markdownComponents = useMarkdownComponents();
2528
2906
  const resolved404 = notFoundResolver ? notFoundResolver(pathname) : undefined;
2529
- const resolveEntry = getEntry || ctxGetEntry || ((c, n) => {
2907
+ const resolveEntry = getEntry || ctxGetEntry || ((c, n, loc) => {
2530
2908
  try {
2531
2909
  const list = idx?.[c];
2532
2910
  if (!Array.isArray(list))
2533
2911
  return;
2534
- const found = list.find((e) => e?.name === n);
2912
+ const found = (loc ? list.find((e) => e?.name === n && e?.locale === loc) : undefined) || list.find((e) => e?.name === n && e?.locale === defaultLocale) || list.find((e) => e?.name === n);
2535
2913
  if (!found)
2536
2914
  return;
2537
2915
  return {
@@ -2543,8 +2921,8 @@ function ContentRoute({
2543
2921
  return;
2544
2922
  }
2545
2923
  });
2546
- const entry = inferredName && resolveEntry ? resolveEntry(collection, inferredName) : undefined;
2547
- const initialComp = useMemo9(() => {
2924
+ const entry = inferredName && resolveEntry ? resolveEntry(collection, inferredName, activeLocale) : undefined;
2925
+ const initialComp = useMemo11(() => {
2548
2926
  try {
2549
2927
  const g = globalThis;
2550
2928
  const mod = g.__REROUTE_SSR_MODULES__?.[key];
@@ -2554,8 +2932,8 @@ function ContentRoute({
2554
2932
  }
2555
2933
  } catch {}
2556
2934
  if (typeof window !== "undefined") {
2557
- const store = window.__REROUTE_MODULES__ || {};
2558
- const cached = store[key];
2935
+ const store2 = window.__REROUTE_MODULES__ || {};
2936
+ const cached = store2[key];
2559
2937
  if (cached) {
2560
2938
  const C = cached.default || cached;
2561
2939
  return toComponent(C);
@@ -2578,8 +2956,8 @@ function ContentRoute({
2578
2956
  if (g.__REROUTE_SSR_MODULES__?.[key]) {
2579
2957
  hasInitialContent = true;
2580
2958
  } else if (typeof window !== "undefined") {
2581
- const store = window.__REROUTE_MODULES__ || {};
2582
- if (store[key]) {
2959
+ const store2 = window.__REROUTE_MODULES__ || {};
2960
+ if (store2[key]) {
2583
2961
  hasInitialContent = true;
2584
2962
  }
2585
2963
  } else if (entry?.component) {
@@ -2710,11 +3088,11 @@ function ContentRoute({
2710
3088
  const compProps = markdownComponents ? { components: markdownComponents } : {};
2711
3089
  const isServer = typeof window === "undefined";
2712
3090
  if (isServer) {
2713
- return /* @__PURE__ */ jsx5("div", {
3091
+ return /* @__PURE__ */ jsx6("div", {
2714
3092
  "data-reroute": "content",
2715
3093
  "data-reroute-key": key,
2716
3094
  ref: containerRef,
2717
- children: /* @__PURE__ */ jsx5(Comp, {
3095
+ children: /* @__PURE__ */ jsx6(Comp, {
2718
3096
  ...compProps
2719
3097
  })
2720
3098
  });
@@ -2722,18 +3100,18 @@ function ContentRoute({
2722
3100
  const capturedHtml = getCapturedHtml(key);
2723
3101
  const hasLoadedModule = !!globalThis.__REROUTE_SSR_MODULES__?.[key] || !!globalThis.__REROUTE_MODULES__?.[key];
2724
3102
  if (capturedHtml && !hasLoadedModule) {
2725
- return /* @__PURE__ */ jsx5("div", {
3103
+ return /* @__PURE__ */ jsx6("div", {
2726
3104
  "data-reroute": "content",
2727
3105
  "data-reroute-key": key,
2728
3106
  ref: containerRef,
2729
3107
  dangerouslySetInnerHTML: { __html: capturedHtml }
2730
3108
  });
2731
3109
  }
2732
- return /* @__PURE__ */ jsx5("div", {
3110
+ return /* @__PURE__ */ jsx6("div", {
2733
3111
  "data-reroute": "content",
2734
3112
  "data-reroute-key": key,
2735
3113
  ref: containerRef,
2736
- children: /* @__PURE__ */ jsx5(Comp, {
3114
+ children: /* @__PURE__ */ jsx6(Comp, {
2737
3115
  ...compProps
2738
3116
  })
2739
3117
  });
@@ -2744,7 +3122,7 @@ import {
2744
3122
  useRef as useRef2,
2745
3123
  useState as useState9
2746
3124
  } from "react";
2747
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
3125
+ import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
2748
3126
  var DEFAULT_DEVICE_SIZES = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
2749
3127
  function generateSrcSet(src, width, quality, format, loader) {
2750
3128
  const sizes = width ? DEFAULT_DEVICE_SIZES.filter((size) => size <= width * 2) : DEFAULT_DEVICE_SIZES;
@@ -2901,7 +3279,7 @@ function Image({
2901
3279
  height: "100%"
2902
3280
  },
2903
3281
  children: [
2904
- showSpinner && !isLoaded && !hasError && /* @__PURE__ */ jsx6("span", {
3282
+ showSpinner && !isLoaded && !hasError && /* @__PURE__ */ jsx7("span", {
2905
3283
  style: {
2906
3284
  position: "absolute",
2907
3285
  inset: 0,
@@ -2912,7 +3290,7 @@ function Image({
2912
3290
  zIndex: 1,
2913
3291
  pointerEvents: "none"
2914
3292
  },
2915
- children: spinner || /* @__PURE__ */ jsx6("span", {
3293
+ children: spinner || /* @__PURE__ */ jsx7("span", {
2916
3294
  style: {
2917
3295
  display: "block",
2918
3296
  width: `${spinnerSize}px`,
@@ -2924,7 +3302,7 @@ function Image({
2924
3302
  }
2925
3303
  })
2926
3304
  }),
2927
- placeholder === "blur" && placeholderSrc && !isLoaded && !hasError && /* @__PURE__ */ jsx6("img", {
3305
+ placeholder === "blur" && placeholderSrc && !isLoaded && !hasError && /* @__PURE__ */ jsx7("img", {
2928
3306
  src: placeholderSrc,
2929
3307
  draggable,
2930
3308
  alt: "",
@@ -2940,7 +3318,7 @@ function Image({
2940
3318
  zIndex: -1
2941
3319
  }
2942
3320
  }),
2943
- /* @__PURE__ */ jsx6("img", {
3321
+ /* @__PURE__ */ jsx7("img", {
2944
3322
  ref: imgRef,
2945
3323
  draggable,
2946
3324
  src: priority || supportsNativeLazyLoading() ? imageUrl : undefined,
@@ -2959,7 +3337,7 @@ function Image({
2959
3337
  className,
2960
3338
  ...props
2961
3339
  }),
2962
- showSpinner && !isLoaded && /* @__PURE__ */ jsx6("style", {
3340
+ showSpinner && !isLoaded && /* @__PURE__ */ jsx7("style", {
2963
3341
  children: `
2964
3342
  @keyframes reroute-spin {
2965
3343
  0% { transform: rotate(0deg); }
@@ -2969,7 +3347,7 @@ function Image({
2969
3347
  })
2970
3348
  ]
2971
3349
  }),
2972
- showCaption && /* @__PURE__ */ jsx6("em", {
3350
+ showCaption && /* @__PURE__ */ jsx7("em", {
2973
3351
  style: {
2974
3352
  display: "block",
2975
3353
  fontSize: "75%",
@@ -2985,8 +3363,8 @@ function Image({
2985
3363
  });
2986
3364
  }
2987
3365
  // packages/react/src/components/Link.tsx
2988
- import { useCallback as useCallback5, useContext as useContext3, useMemo as useMemo10 } from "react";
2989
- import { jsx as jsx7 } from "react/jsx-runtime";
3366
+ import { useCallback as useCallback7, useContext as useContext4, useMemo as useMemo12 } from "react";
3367
+ import { jsx as jsx8 } from "react/jsx-runtime";
2990
3368
  function parseLocalUrl(to) {
2991
3369
  if (typeof window === "undefined")
2992
3370
  return null;
@@ -3026,35 +3404,35 @@ function dispatchDataEvent(detail) {
3026
3404
  function storeAndDispatchData(path, payload, silent = false) {
3027
3405
  if (!payload || typeof payload !== "object")
3028
3406
  return;
3029
- const store = getRerouteDataStore();
3407
+ const store2 = getRerouteDataStore();
3030
3408
  if (payload.__reroute_multiple__ === true) {
3031
3409
  const keys = Object.keys(payload).filter((k) => k !== "__reroute_multiple__");
3032
3410
  for (const key of keys) {
3033
- store[key] = payload[key];
3411
+ store2[key] = payload[key];
3034
3412
  }
3035
3413
  if (!silent)
3036
3414
  dispatchDataEvent({ keys });
3037
3415
  } else if (payload.__flatten__ === true || payload.__reroute_flattened__ === true) {
3038
3416
  const keys = Object.keys(payload).filter((k) => k !== "__flatten__" && k !== "__reroute_flattened__");
3039
3417
  for (const key of keys) {
3040
- store[key] = payload[key];
3418
+ store2[key] = payload[key];
3041
3419
  }
3042
- store[path] = payload;
3420
+ store2[path] = payload;
3043
3421
  if (!silent)
3044
3422
  dispatchDataEvent({ keys: [...keys, path] });
3045
3423
  } else {
3046
- store[path] = payload;
3424
+ store2[path] = payload;
3047
3425
  if (!silent)
3048
3426
  dispatchDataEvent({ key: path });
3049
3427
  }
3050
3428
  }
3051
3429
  function needsDataPrefetch(path, inferred, matchRoute) {
3052
3430
  const isDynamic = !!matchRoute?.(path)?.route?.isDynamic;
3053
- const store = getRerouteDataStore();
3431
+ const store2 = getRerouteDataStore();
3054
3432
  const hasRealContent = inferred?.module !== undefined;
3055
3433
  if (hasRealContent)
3056
3434
  return false;
3057
- if (store[path] !== undefined)
3435
+ if (store2[path] !== undefined)
3058
3436
  return false;
3059
3437
  const route = matchRoute?.(path)?.route;
3060
3438
  const hasSSRData = !!(route?.ssr && typeof route.ssr === "object" && typeof route.ssr.data === "function");
@@ -3131,18 +3509,20 @@ function Link({
3131
3509
  draggable = false,
3132
3510
  ...props
3133
3511
  }) {
3134
- const routerContext = useContext3(RouterContext);
3512
+ const routerContext = useContext4(RouterContext);
3135
3513
  const router = useRouter();
3136
3514
  const resolver = useContentResolver();
3137
3515
  const contentIndex = useContentIndex();
3138
3516
  const ensureCollection = useContentLoadCollection();
3517
+ const { localizePath, enabled: i18nEnabled } = useLocaleContext();
3139
3518
  const hasRouter = !!routerContext;
3140
3519
  const { navigate, matchRoute } = router || {
3141
3520
  navigate: () => {},
3142
3521
  matchRoute: () => null
3143
3522
  };
3144
- const inferred = useMemo10(() => resolver ? resolver(String(to)) : undefined, [resolver, to]);
3145
- const handleSameRouteNavigation = useCallback5((localUrl) => {
3523
+ const resolvedTo = useMemo12(() => i18nEnabled ? localizePath(String(to)) : String(to), [i18nEnabled, localizePath, to]);
3524
+ const inferred = useMemo12(() => resolver ? resolver(resolvedTo) : undefined, [resolver, resolvedTo]);
3525
+ const handleSameRouteNavigation = useCallback7((localUrl) => {
3146
3526
  const currentPath = window.location.pathname + window.location.search;
3147
3527
  if (localUrl.fullPath !== currentPath)
3148
3528
  return false;
@@ -3153,14 +3533,17 @@ function Link({
3153
3533
  if (element) {
3154
3534
  element.scrollIntoView({ behavior: "smooth" });
3155
3535
  } else {
3156
- navigate(fragment ? `${to}#${fragment}` : to, { replace, state });
3536
+ navigate(fragment ? `${resolvedTo}#${fragment}` : resolvedTo, {
3537
+ replace,
3538
+ state
3539
+ });
3157
3540
  }
3158
3541
  } else {
3159
3542
  window.scrollTo({ top: 0, behavior: "smooth" });
3160
3543
  }
3161
3544
  return true;
3162
- }, [fragment, navigate, replace, state, to]);
3163
- const triggerPrefetch = useCallback5((localUrl, options) => {
3545
+ }, [fragment, navigate, replace, state, resolvedTo]);
3546
+ const triggerPrefetch = useCallback7((localUrl, options) => {
3164
3547
  if (needsDataPrefetch(localUrl.path, inferred, matchRoute)) {
3165
3548
  if (options?.withTimeout) {
3166
3549
  prefetchRouteDataWithTimeout(localUrl.path);
@@ -3173,27 +3556,30 @@ function Link({
3173
3556
  prefetchContentModule(inferred, contentIndex, ensureCollection);
3174
3557
  }
3175
3558
  }, [inferred, ensureCollection, contentIndex, matchRoute]);
3176
- const handleClick = useCallback5(async (e) => {
3559
+ const handleClick = useCallback7(async (e) => {
3177
3560
  onClick?.(e);
3178
3561
  if (!hasRouter)
3179
3562
  return;
3180
3563
  if (isModifiedClick(e, props.target))
3181
3564
  return;
3182
- if (shouldSkipInterception(String(to)))
3565
+ if (shouldSkipInterception(resolvedTo))
3183
3566
  return;
3184
3567
  e.preventDefault();
3185
- const localUrl = parseLocalUrl(String(to));
3568
+ const localUrl = parseLocalUrl(resolvedTo);
3186
3569
  if (localUrl && handleSameRouteNavigation(localUrl))
3187
3570
  return;
3188
3571
  if (prefetch && localUrl) {
3189
3572
  await triggerPrefetch(localUrl, { withTimeout: true });
3190
3573
  }
3191
- navigate(fragment ? `${to}#${fragment}` : to, { replace, state });
3574
+ navigate(fragment ? `${resolvedTo}#${fragment}` : resolvedTo, {
3575
+ replace,
3576
+ state
3577
+ });
3192
3578
  }, [
3193
3579
  onClick,
3194
3580
  hasRouter,
3195
3581
  props.target,
3196
- to,
3582
+ resolvedTo,
3197
3583
  handleSameRouteNavigation,
3198
3584
  prefetch,
3199
3585
  triggerPrefetch,
@@ -3202,24 +3588,24 @@ function Link({
3202
3588
  replace,
3203
3589
  state
3204
3590
  ]);
3205
- const handleMouseEnter = useCallback5((e) => {
3591
+ const handleMouseEnter = useCallback7((e) => {
3206
3592
  if (prefetch) {
3207
- const localUrl = parseLocalUrl(String(to));
3593
+ const localUrl = parseLocalUrl(resolvedTo);
3208
3594
  if (localUrl)
3209
3595
  triggerPrefetch(localUrl, { silent: true });
3210
3596
  }
3211
3597
  onMouseEnter?.(e);
3212
- }, [prefetch, to, triggerPrefetch, onMouseEnter]);
3213
- const handleFocus = useCallback5((e) => {
3598
+ }, [prefetch, resolvedTo, triggerPrefetch, onMouseEnter]);
3599
+ const handleFocus = useCallback7((e) => {
3214
3600
  if (prefetch) {
3215
- const localUrl = parseLocalUrl(String(to));
3601
+ const localUrl = parseLocalUrl(resolvedTo);
3216
3602
  if (localUrl)
3217
3603
  triggerPrefetch(localUrl, { silent: true });
3218
3604
  }
3219
3605
  onFocus?.(e);
3220
- }, [prefetch, to, triggerPrefetch, onFocus]);
3221
- const href = fragment ? `${to}#${fragment}` : to;
3222
- return /* @__PURE__ */ jsx7("a", {
3606
+ }, [prefetch, resolvedTo, triggerPrefetch, onFocus]);
3607
+ const href = fragment ? `${resolvedTo}#${fragment}` : resolvedTo;
3608
+ return /* @__PURE__ */ jsx8("a", {
3223
3609
  href,
3224
3610
  onClick: handleClick,
3225
3611
  onMouseEnter: handleMouseEnter,
@@ -3230,7 +3616,7 @@ function Link({
3230
3616
  }
3231
3617
  // packages/react/src/components/Markdown.tsx
3232
3618
  import { Streamdown } from "streamdown";
3233
- import { jsx as jsx8 } from "react/jsx-runtime";
3619
+ import { jsx as jsx9 } from "react/jsx-runtime";
3234
3620
  function Markdown({
3235
3621
  children,
3236
3622
  className,
@@ -3240,9 +3626,9 @@ function Markdown({
3240
3626
  }) {
3241
3627
  const finalRemarkPlugins = [...remarkPlugins];
3242
3628
  const finalRehypePlugins = [...rehypePlugins];
3243
- return /* @__PURE__ */ jsx8("div", {
3629
+ return /* @__PURE__ */ jsx9("div", {
3244
3630
  className,
3245
- children: /* @__PURE__ */ jsx8(Streamdown, {
3631
+ children: /* @__PURE__ */ jsx9(Streamdown, {
3246
3632
  remarkPlugins: finalRemarkPlugins,
3247
3633
  rehypePlugins: finalRehypePlugins,
3248
3634
  components,
@@ -3251,11 +3637,11 @@ function Markdown({
3251
3637
  });
3252
3638
  }
3253
3639
  // packages/react/src/components/Outlet.tsx
3254
- import { useContext as useContext4 } from "react";
3255
- import { jsx as jsx9, Fragment as Fragment2 } from "react/jsx-runtime";
3640
+ import { useContext as useContext5 } from "react";
3641
+ import { jsx as jsx10, Fragment as Fragment2 } from "react/jsx-runtime";
3256
3642
  function Outlet() {
3257
- const outletContent = useContext4(OutletContext);
3258
- return /* @__PURE__ */ jsx9(Fragment2, {
3643
+ const outletContent = useContext5(OutletContext);
3644
+ return /* @__PURE__ */ jsx10(Fragment2, {
3259
3645
  children: outletContent
3260
3646
  });
3261
3647
  }
@@ -3274,7 +3660,7 @@ async function collectionSearch(options) {
3274
3660
  return null;
3275
3661
  const indexData = JSON.parse(await file.text());
3276
3662
  const entries = indexData.entries || [];
3277
- const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 1);
3663
+ const terms = query.toLowerCase().split(/\s+/).filter((t2) => t2.length > 1);
3278
3664
  if (terms.length === 0)
3279
3665
  return null;
3280
3666
  const collectionsFilter = searchParams?.get("collections")?.split(",").filter(Boolean);
@@ -3362,6 +3748,8 @@ export {
3362
3748
  useParams,
3363
3749
  useNavigate,
3364
3750
  useMarkdownComponents,
3751
+ useLocaleContext,
3752
+ useLocale,
3365
3753
  useLlms,
3366
3754
  useLayoutData,
3367
3755
  useFeed,
@@ -3371,6 +3759,7 @@ export {
3371
3759
  useContentIndex,
3372
3760
  useContentGetEntry,
3373
3761
  useContent,
3762
+ t,
3374
3763
  storeAndDispatchData,
3375
3764
  shouldSkipInterception,
3376
3765
  preloadRoute,
@@ -3379,12 +3768,16 @@ export {
3379
3768
  prefetchContentModule,
3380
3769
  prefetchContent,
3381
3770
  parseLocalUrl,
3771
+ parseContentPath,
3382
3772
  parseContentHref,
3383
3773
  needsDataPrefetch,
3774
+ localizeHref,
3775
+ localizeContentHref,
3384
3776
  isModifiedClick,
3385
3777
  getRerouteDataStore,
3386
3778
  fetchRouteData,
3387
3779
  dispatchDataEvent,
3780
+ createTranslator,
3388
3781
  createResolverFromGetEntry,
3389
3782
  createLazyRoute,
3390
3783
  collectionSearch,
@@ -3398,6 +3791,7 @@ export {
3398
3791
  OutletContext,
3399
3792
  Outlet,
3400
3793
  Markdown,
3794
+ LocaleProvider,
3401
3795
  Link,
3402
3796
  Image,
3403
3797
  ContentRoute,
@@ -3405,4 +3799,4 @@ export {
3405
3799
  ClientOnly
3406
3800
  };
3407
3801
 
3408
- //# debugId=9B63CBF08200528F64756E2164756E21
3802
+ //# debugId=C69A90B48CACDDC864756E2164756E21