reroute-js 0.45.12-beta.1 → 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 (239) 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 +980 -337
  8. package/cli/bin.js.map +29 -21
  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 +667 -117
  41. package/core/index.js.map +28 -20
  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/index.d.ts +2 -2
  74. package/core/src/og/meta.d.ts +2 -2
  75. package/core/src/og/render.d.ts +2 -2
  76. package/core/src/og/types.d.ts +2 -2
  77. package/core/src/robots/discovery.d.ts +2 -2
  78. package/core/src/robots/generator.d.ts +2 -2
  79. package/core/src/robots/index.d.ts +2 -2
  80. package/core/src/robots/policies.d.ts +2 -2
  81. package/core/src/rss/discovery.d.ts +4 -2
  82. package/core/src/rss/discovery.d.ts.map +1 -1
  83. package/core/src/rss/generator.d.ts +2 -2
  84. package/core/src/rss/index.d.ts +2 -2
  85. package/core/src/sitemap/discovery.d.ts +7 -2
  86. package/core/src/sitemap/discovery.d.ts.map +1 -1
  87. package/core/src/sitemap/generator.d.ts +2 -2
  88. package/core/src/sitemap/generator.d.ts.map +1 -1
  89. package/core/src/sitemap/index.d.ts +2 -2
  90. package/core/src/ssr/index.d.ts +2 -2
  91. package/core/src/ssr/lib/cache.d.ts +2 -2
  92. package/core/src/ssr/lib/cleanup.d.ts +2 -2
  93. package/core/src/ssr/lib/collections.d.ts +2 -2
  94. package/core/src/ssr/lib/compression.d.ts +2 -2
  95. package/core/src/ssr/lib/compute/content.d.ts +2 -9
  96. package/core/src/ssr/lib/compute/content.d.ts.map +1 -1
  97. package/core/src/ssr/lib/compute/index.d.ts +2 -2
  98. package/core/src/ssr/lib/compute/layouts.d.ts +2 -2
  99. package/core/src/ssr/lib/compute/routes.d.ts +2 -2
  100. package/core/src/ssr/lib/compute/routes.d.ts.map +1 -1
  101. package/core/src/ssr/lib/content-path.d.ts +22 -0
  102. package/core/src/ssr/lib/content-path.d.ts.map +1 -0
  103. package/core/src/ssr/lib/data.d.ts +2 -2
  104. package/core/src/ssr/lib/data.d.ts.map +1 -1
  105. package/core/src/ssr/lib/html.d.ts +2 -2
  106. package/core/src/ssr/lib/imports.d.ts +2 -2
  107. package/core/src/ssr/lib/index.d.ts +2 -2
  108. package/core/src/ssr/lib/layouts.d.ts +2 -2
  109. package/core/src/ssr/lib/metadata.d.ts +2 -2
  110. package/core/src/ssr/lib/metadata.d.ts.map +1 -1
  111. package/core/src/ssr/lib/mime.d.ts +2 -2
  112. package/core/src/ssr/lib/modules.d.ts +4 -4
  113. package/core/src/ssr/lib/modules.d.ts.map +1 -1
  114. package/core/src/ssr/lib/path.d.ts +2 -2
  115. package/core/src/ssr/lib/preload.d.ts +2 -2
  116. package/core/src/ssr/lib/preload.d.ts.map +1 -1
  117. package/core/src/ssr/lib/route-match.d.ts +2 -2
  118. package/core/src/ssr/lib/scripts/collections.d.ts +2 -2
  119. package/core/src/ssr/lib/scripts/data.d.ts +3 -3
  120. package/core/src/ssr/lib/scripts/data.d.ts.map +1 -1
  121. package/core/src/ssr/lib/scripts/escape.d.ts +2 -2
  122. package/core/src/ssr/lib/scripts/feeds.d.ts +2 -2
  123. package/core/src/ssr/lib/scripts/index.d.ts +2 -2
  124. package/core/src/ssr/lib/seed.d.ts +2 -2
  125. package/core/src/ssr/lib/seed.d.ts.map +1 -1
  126. package/core/src/ssr/lib/serialize.d.ts +2 -2
  127. package/core/src/ssr/lib/setup.d.ts +3 -3
  128. package/core/src/ssr/lib/setup.d.ts.map +1 -1
  129. package/core/src/ssr/lib/styles.d.ts +2 -2
  130. package/core/src/ssr/lib/template.d.ts +2 -2
  131. package/core/src/ssr/lib/types.d.ts +2 -2
  132. package/core/src/ssr/render.d.ts +4 -2
  133. package/core/src/ssr/render.d.ts.map +1 -1
  134. package/core/src/ssr/stream.d.ts +4 -2
  135. package/core/src/ssr/stream.d.ts.map +1 -1
  136. package/elysia/index.d.ts +2 -2
  137. package/elysia/index.js +872 -177
  138. package/elysia/index.js.map +32 -23
  139. package/elysia/src/index.d.ts +2 -2
  140. package/elysia/src/libs/assets.d.ts +2 -2
  141. package/elysia/src/libs/cache.d.ts +2 -2
  142. package/elysia/src/libs/caching.d.ts +2 -2
  143. package/elysia/src/libs/http.d.ts +2 -2
  144. package/elysia/src/libs/i18n.d.ts +26 -0
  145. package/elysia/src/libs/i18n.d.ts.map +1 -0
  146. package/elysia/src/libs/image.d.ts +2 -2
  147. package/elysia/src/libs/index.d.ts +2 -2
  148. package/elysia/src/libs/llms.d.ts +2 -2
  149. package/elysia/src/libs/response.d.ts +2 -2
  150. package/elysia/src/libs/serving.d.ts +2 -2
  151. package/elysia/src/plugin.d.ts +2 -2
  152. package/elysia/src/routes/artifacts.d.ts +2 -2
  153. package/elysia/src/routes/content.d.ts +2 -2
  154. package/elysia/src/routes/image.d.ts +2 -2
  155. package/elysia/src/routes/index.d.ts +2 -2
  156. package/elysia/src/routes/internal.d.ts +2 -2
  157. package/elysia/src/routes/llms.d.ts +2 -2
  158. package/elysia/src/routes/og.d.ts +2 -2
  159. package/elysia/src/routes/redirects.d.ts +2 -2
  160. package/elysia/src/routes/robots.d.ts +2 -2
  161. package/elysia/src/routes/rss.d.ts +2 -2
  162. package/elysia/src/routes/rss.d.ts.map +1 -1
  163. package/elysia/src/routes/search.d.ts +2 -2
  164. package/elysia/src/routes/search.d.ts.map +1 -1
  165. package/elysia/src/routes/sitemap.d.ts +2 -2
  166. package/elysia/src/routes/ssr.d.ts +2 -2
  167. package/elysia/src/routes/ssr.d.ts.map +1 -1
  168. package/elysia/src/routes/static.d.ts +2 -2
  169. package/elysia/src/types.d.ts +2 -2
  170. package/package.json +7 -6
  171. package/react/index.d.ts +2 -2
  172. package/react/index.js +560 -170
  173. package/react/index.js.map +12 -10
  174. package/react/src/components/ClientOnly.d.ts +2 -2
  175. package/react/src/components/ContentRoute.d.ts +3 -3
  176. package/react/src/components/ContentRoute.d.ts.map +1 -1
  177. package/react/src/components/Image.d.ts +2 -2
  178. package/react/src/components/LazyRoute.d.ts +2 -2
  179. package/react/src/components/Link.d.ts +2 -2
  180. package/react/src/components/Link.d.ts.map +1 -1
  181. package/react/src/components/Markdown.d.ts +2 -2
  182. package/react/src/components/Outlet.d.ts +2 -2
  183. package/react/src/components/index.d.ts +2 -2
  184. package/react/src/hooks/index.d.ts +2 -2
  185. package/react/src/hooks/useContent.d.ts +2 -2
  186. package/react/src/hooks/useContent.d.ts.map +1 -1
  187. package/react/src/hooks/useData.d.ts +2 -2
  188. package/react/src/hooks/useFeed.d.ts +2 -2
  189. package/react/src/hooks/useLayoutData.d.ts +2 -2
  190. package/react/src/hooks/useLlms.d.ts +2 -2
  191. package/react/src/hooks/useNavigate.d.ts +2 -2
  192. package/react/src/hooks/useParams.d.ts +2 -2
  193. package/react/src/hooks/useRouter.d.ts +2 -2
  194. package/react/src/hooks/useSearch.d.ts +2 -2
  195. package/react/src/hooks/useSearch.d.ts.map +1 -1
  196. package/react/src/hooks/useSearchParams.d.ts +2 -2
  197. package/react/src/hooks/useToc.d.ts +2 -2
  198. package/react/src/i18n/LocaleProvider.d.ts +49 -0
  199. package/react/src/i18n/LocaleProvider.d.ts.map +1 -0
  200. package/react/src/i18n/helpers.d.ts +24 -0
  201. package/react/src/i18n/helpers.d.ts.map +1 -0
  202. package/react/src/i18n/index.d.ts +13 -0
  203. package/react/src/i18n/index.d.ts.map +1 -0
  204. package/react/src/index.d.ts +3 -2
  205. package/react/src/index.d.ts.map +1 -1
  206. package/react/src/lib/collection.d.ts +2 -2
  207. package/react/src/lib/content.d.ts +4 -3
  208. package/react/src/lib/content.d.ts.map +1 -1
  209. package/react/src/lib/head.d.ts +2 -2
  210. package/react/src/lib/index.d.ts +2 -2
  211. package/react/src/lib/lazy-route.d.ts +2 -2
  212. package/react/src/lib/route-loader.d.ts +2 -2
  213. package/react/src/providers/ContentProvider.d.ts +3 -3
  214. package/react/src/providers/ContentProvider.d.ts.map +1 -1
  215. package/react/src/providers/RerouteProvider.d.ts +8 -6
  216. package/react/src/providers/RerouteProvider.d.ts.map +1 -1
  217. package/react/src/providers/RouterProvider.d.ts +2 -2
  218. package/react/src/providers/index.d.ts +2 -2
  219. package/react/src/types/any.d.ts +2 -2
  220. package/react/src/types/index.d.ts +2 -2
  221. package/react/src/types/router.d.ts +2 -2
  222. package/telemetry/react.d.ts +2 -2
  223. package/telemetry/react.js +3 -3
  224. package/telemetry/react.js.map +1 -1
  225. package/telemetry/server.d.ts +2 -2
  226. package/telemetry/server.js +56 -4
  227. package/telemetry/server.js.map +20 -15
  228. package/telemetry/src/react/api.d.ts +2 -2
  229. package/telemetry/src/react/context.d.ts +2 -2
  230. package/telemetry/src/react/index.d.ts +2 -2
  231. package/telemetry/src/react/telemetry.d.ts +2 -2
  232. package/telemetry/src/server/context.d.ts +2 -2
  233. package/telemetry/src/server/headers/extractor.d.ts +2 -2
  234. package/telemetry/src/server/headers/index.d.ts +2 -2
  235. package/telemetry/src/server/headers/presets.d.ts +2 -2
  236. package/telemetry/src/server/index.d.ts +2 -2
  237. package/telemetry/src/server/instrumentation.d.ts +2 -2
  238. package/telemetry/src/server/plugin.d.ts +2 -2
  239. package/telemetry/src/server/sourcemap.d.ts +2 -2
package/react/index.js CHANGED
@@ -1,9 +1,9 @@
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
  */
@@ -397,32 +397,310 @@ import {
397
397
  isValidElement,
398
398
  useEffect as useEffect8,
399
399
  useLayoutEffect,
400
- useMemo as useMemo9,
400
+ useMemo as useMemo11,
401
401
  useRef,
402
402
  useState as useState8
403
403
  } from "react";
404
404
  import { flushSync as flushSync2 } from "react-dom";
405
405
 
406
406
  // packages/react/src/hooks/useContent.ts
407
- 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";
408
408
 
409
- // 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
410
503
  import {
411
504
  createContext,
412
505
  useCallback,
413
506
  useContext,
414
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,
415
686
  useState as useState2
416
687
  } from "react";
417
688
 
418
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
+ }
419
693
  function parseContentHref(href) {
420
694
  try {
421
695
  const url = new URL(href, "http://local");
422
- const [collection, name] = url.pathname.split("/").filter(Boolean);
423
- if (!(collection && name))
696
+ const parts = url.pathname.split("/").filter(Boolean);
697
+ if (parts.length < 2)
424
698
  return;
425
- 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 };
426
704
  } catch {
427
705
  return;
428
706
  }
@@ -433,7 +711,7 @@ function createResolverFromGetEntry(getEntry) {
433
711
  if (!parsed)
434
712
  return;
435
713
  try {
436
- const entry = getEntry(parsed.collection, parsed.name);
714
+ const entry = getEntry(parsed.collection, parsed.name, parsed.locale);
437
715
  if (!entry)
438
716
  return parsed;
439
717
  const moduleUrl = entry?.module;
@@ -445,12 +723,33 @@ function createResolverFromGetEntry(getEntry) {
445
723
  }
446
724
 
447
725
  // packages/react/src/providers/ContentProvider.tsx
448
- import { jsx as jsx2 } from "react/jsx-runtime";
449
- var ContentRegistryContext = createContext(null);
450
- var ContentIndexContext = createContext(null);
451
- var ContentGetEntryContext = createContext(null);
452
- var ContentLoadCollectionContext = createContext(null);
453
- 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);
454
753
  function ContentProvider({
455
754
  children,
456
755
  resolveByHref,
@@ -486,28 +785,14 @@ function ContentProvider({
486
785
  return result;
487
786
  });
488
787
  const entryFn = getEntry || null;
489
- const resolver = useMemo(() => {
788
+ const resolver = useMemo2(() => {
490
789
  if (typeof resolveByHref === "function")
491
790
  return resolveByHref;
492
791
  if (typeof getEntry === "function")
493
792
  return createResolverFromGetEntry(getEntry);
494
- return (href) => {
495
- const parsed = parseContentHref(href);
496
- if (!parsed)
497
- return;
498
- try {
499
- const list = idx?.[parsed.collection];
500
- if (Array.isArray(list)) {
501
- const found = list.find((e) => e?.name === parsed.name);
502
- if (found && typeof found.module === "string") {
503
- return { ...parsed, module: found.module };
504
- }
505
- }
506
- } catch {}
507
- return parsed;
508
- };
793
+ return (href) => resolveFromIndex(href, idx);
509
794
  }, [resolveByHref, getEntry, idx]);
510
- const ensureCollection = useCallback(async (collection) => {
795
+ const ensureCollection = useCallback2(async (collection) => {
511
796
  try {
512
797
  const existing = idx[collection];
513
798
  const w = typeof window !== "undefined" ? window : undefined;
@@ -531,15 +816,15 @@ function ContentProvider({
531
816
  return;
532
817
  }
533
818
  }, [idx, loadCollection]);
534
- return /* @__PURE__ */ jsx2(ContentRegistryContext.Provider, {
819
+ return /* @__PURE__ */ jsx3(ContentRegistryContext.Provider, {
535
820
  value: resolver,
536
- children: /* @__PURE__ */ jsx2(ContentIndexContext.Provider, {
821
+ children: /* @__PURE__ */ jsx3(ContentIndexContext.Provider, {
537
822
  value: idx,
538
- children: /* @__PURE__ */ jsx2(ContentGetEntryContext.Provider, {
823
+ children: /* @__PURE__ */ jsx3(ContentGetEntryContext.Provider, {
539
824
  value: entryFn,
540
- children: /* @__PURE__ */ jsx2(ContentLoadCollectionContext.Provider, {
825
+ children: /* @__PURE__ */ jsx3(ContentLoadCollectionContext.Provider, {
541
826
  value: ensureCollection,
542
- children: /* @__PURE__ */ jsx2(MarkdownComponentsContext.Provider, {
827
+ children: /* @__PURE__ */ jsx3(MarkdownComponentsContext.Provider, {
543
828
  value: markdownComponents || null,
544
829
  children
545
830
  })
@@ -549,23 +834,23 @@ function ContentProvider({
549
834
  });
550
835
  }
551
836
  function useContentResolver() {
552
- return useContext(ContentRegistryContext);
837
+ return useContext2(ContentRegistryContext);
553
838
  }
554
839
  function useContentIndex() {
555
- return useContext(ContentIndexContext);
840
+ return useContext2(ContentIndexContext);
556
841
  }
557
842
  function useContentGetEntry() {
558
- return useContext(ContentGetEntryContext);
843
+ return useContext2(ContentGetEntryContext);
559
844
  }
560
845
  function useContentLoadCollection() {
561
- return useContext(ContentLoadCollectionContext);
846
+ return useContext2(ContentLoadCollectionContext);
562
847
  }
563
848
  function useMarkdownComponents() {
564
- return useContext(MarkdownComponentsContext);
849
+ return useContext2(MarkdownComponentsContext);
565
850
  }
566
851
 
567
852
  // packages/react/src/hooks/useSearch.ts
568
- 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";
569
854
  function useSearch(params) {
570
855
  const {
571
856
  query,
@@ -575,7 +860,7 @@ function useSearch(params) {
575
860
  enabled = true,
576
861
  debounce = 300
577
862
  } = params;
578
- const stableCollections = useMemo2(() => collections, [collections]);
863
+ const stableCollections = useMemo3(() => collections, [collections]);
579
864
  const [results, setResults] = useState3([]);
580
865
  const [total, setTotal] = useState3(0);
581
866
  const [page, setPage] = useState3(paramPage);
@@ -583,7 +868,7 @@ function useSearch(params) {
583
868
  const [totalPages, setTotalPages] = useState3(0);
584
869
  const [isLoading, setIsLoading] = useState3(false);
585
870
  const [error, setError] = useState3(null);
586
- const performSearch = useCallback2(async (searchQuery, searchPage) => {
871
+ const performSearch = useCallback3(async (searchQuery, searchPage) => {
587
872
  if (!searchQuery.trim()) {
588
873
  setResults([]);
589
874
  setTotal(0);
@@ -607,6 +892,12 @@ function useSearch(params) {
607
892
  if (paramPageSize) {
608
893
  params2.set("pageSize", String(paramPageSize));
609
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 {}
610
901
  const response = await fetch(`/__reroute_search?${params2.toString()}`);
611
902
  if (!response.ok) {
612
903
  const errorData = await response.json().catch(() => ({}));
@@ -651,7 +942,7 @@ function useSearch(params) {
651
942
  }, debounce);
652
943
  return () => clearTimeout(timeoutId);
653
944
  }, [query, paramPage, enabled, debounce, performSearch]);
654
- const search = useCallback2(async (newQuery, newPage) => {
945
+ const search = useCallback3(async (newQuery, newPage) => {
655
946
  await performSearch(newQuery, newPage);
656
947
  }, [performSearch]);
657
948
  return {
@@ -667,6 +958,24 @@ function useSearch(params) {
667
958
  }
668
959
 
669
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
+ }
670
979
  function sortByDate(order) {
671
980
  return (a, b) => {
672
981
  const da = a?.meta && a.meta?.date ? Date.parse(String(a.meta.date)) : 0;
@@ -829,11 +1138,11 @@ function prefetchContent(entry) {
829
1138
  const w = window;
830
1139
  if (!w.__REROUTE_MODULES__)
831
1140
  w.__REROUTE_MODULES__ = {};
832
- const store = w.__REROUTE_MODULES__;
833
- if (store[key])
1141
+ const store2 = w.__REROUTE_MODULES__;
1142
+ if (store2[key])
834
1143
  return;
835
1144
  import(modUrl).then((m) => {
836
- store[key] = m;
1145
+ store2[key] = m;
837
1146
  }).catch(() => {});
838
1147
  } catch {}
839
1148
  }
@@ -874,6 +1183,7 @@ function useContent(params) {
874
1183
  }
875
1184
  const index = useContentIndex();
876
1185
  const loadCollection = useContentLoadCollection();
1186
+ const { locale, defaultLocale, enabled: i18nEnabled } = useLocale();
877
1187
  const [_ready, setReady] = useState4(() => {
878
1188
  const have = index?.[collection];
879
1189
  return Array.isArray(have) && have.length > 0;
@@ -935,12 +1245,19 @@ function useContent(params) {
935
1245
  cancelled = true;
936
1246
  };
937
1247
  }, [collection, index, loadCollection, limit, filter, fields]);
938
- const items = useMemo3(() => {
1248
+ const items = useMemo4(() => {
939
1249
  const source = index || {};
940
1250
  const list = source?.[collection];
941
1251
  if (!Array.isArray(list) || list.length === 0)
942
1252
  return [];
943
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
+ }
944
1261
  cloned = applyFilter(cloned, filter);
945
1262
  if (typeof sort === "function") {
946
1263
  cloned = cloned.sort(sort);
@@ -974,14 +1291,23 @@ function useContent(params) {
974
1291
  } catch {}
975
1292
  }
976
1293
  return cloned;
977
- }, [index, collection, sort, limit, filter]);
1294
+ }, [
1295
+ index,
1296
+ collection,
1297
+ sort,
1298
+ limit,
1299
+ filter,
1300
+ i18nEnabled,
1301
+ locale,
1302
+ defaultLocale
1303
+ ]);
978
1304
  useEffect3(() => {
979
1305
  if (typeof window === "undefined")
980
1306
  return;
981
1307
  const handler = (e) => {
982
1308
  const detail = e.detail;
983
1309
  if (detail?.collection === collection) {
984
- setContentLoadTick((t) => t + 1);
1310
+ setContentLoadTick((t2) => t2 + 1);
985
1311
  }
986
1312
  };
987
1313
  window.addEventListener("__reroute_content_loading__", handler);
@@ -991,8 +1317,8 @@ function useContent(params) {
991
1317
  window.removeEventListener("__reroute_content_loaded__", handler);
992
1318
  };
993
1319
  }, [collection]);
994
- const prefetch = useCallback3((entry) => prefetchContent(entry), []);
995
- const hasLoadingModules = useMemo3(() => {
1320
+ const prefetch = useCallback4((entry) => prefetchContent(entry), []);
1321
+ const hasLoadingModules = useMemo4(() => {
996
1322
  if (typeof window === "undefined") {
997
1323
  return false;
998
1324
  }
@@ -1009,17 +1335,20 @@ function useContent(params) {
1009
1335
  return { items, isLoading, prefetch };
1010
1336
  }
1011
1337
  // packages/react/src/hooks/useData.ts
1012
- 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";
1013
1339
 
1014
1340
  // packages/react/src/hooks/useRouter.tsx
1015
- 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
+
1016
1345
  // packages/react/src/providers/RouterProvider.tsx
1017
1346
  import React, {
1018
- createContext as createContext2,
1019
- useCallback as useCallback4,
1347
+ createContext as createContext3,
1348
+ useCallback as useCallback5,
1020
1349
  useEffect as useEffect4,
1021
- useMemo as useMemo4,
1022
- useSyncExternalStore
1350
+ useMemo as useMemo5,
1351
+ useSyncExternalStore as useSyncExternalStore2
1023
1352
  } from "react";
1024
1353
  import { flushSync } from "react-dom";
1025
1354
 
@@ -1167,10 +1496,10 @@ function applyRouteHead(head) {
1167
1496
  }
1168
1497
 
1169
1498
  // packages/react/src/providers/RouterProvider.tsx
1170
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1499
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1171
1500
  var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "undefined";
1172
- var OutletContext = createContext2(null);
1173
- var RouterContext = createContext2(null);
1501
+ var OutletContext = createContext3(null);
1502
+ var RouterContext = createContext3(null);
1174
1503
  var listeners = [];
1175
1504
  var currentLocation = isBrowser2 ? {
1176
1505
  pathname: window.location.pathname,
@@ -1212,7 +1541,7 @@ function applyHeadIfStillOnPage(pathnameToUse, payload, matchRoute) {
1212
1541
  console.error("[RouterProvider] Error applying head after lazy fetch:", e);
1213
1542
  }
1214
1543
  }
1215
- } else {}
1544
+ }
1216
1545
  });
1217
1546
  }
1218
1547
  function processLazyFetchResponse(json, pathnameToUse, matchRoute) {
@@ -1293,7 +1622,7 @@ function applyRouteHeadAndLang(currentPathname, pathname, target, matchRoute) {
1293
1622
  applyLang(ssr.lang);
1294
1623
  } catch {}
1295
1624
  }
1296
- function subscribe(listener) {
1625
+ function subscribe2(listener) {
1297
1626
  if (!isBrowser2)
1298
1627
  return () => {};
1299
1628
  listeners.push(listener);
@@ -1301,7 +1630,7 @@ function subscribe(listener) {
1301
1630
  listeners = listeners.filter((l) => l !== listener);
1302
1631
  };
1303
1632
  }
1304
- function getSnapshot() {
1633
+ function getSnapshot2() {
1305
1634
  return currentLocation;
1306
1635
  }
1307
1636
  function emitChange() {
@@ -1461,8 +1790,8 @@ function RouterProvider({
1461
1790
  serverSnapshotRef.current = { pathname: pathOnly, search, hash };
1462
1791
  }
1463
1792
  }
1464
- const getServerSnapshot = useCallback4(() => serverSnapshotRef.current, []);
1465
- const location = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) || currentLocation;
1793
+ const getServerSnapshot2 = useCallback5(() => serverSnapshotRef.current, []);
1794
+ const location = useSyncExternalStore2(subscribe2, getSnapshot2, getServerSnapshot2) || currentLocation;
1466
1795
  useEffect4(() => {
1467
1796
  if (!isBrowser2)
1468
1797
  return;
@@ -1476,10 +1805,10 @@ function RouterProvider({
1476
1805
  emitChange();
1477
1806
  }
1478
1807
  }, []);
1479
- const target = useMemo4(() => matchRoute(location.pathname), [location.pathname, matchRoute]);
1808
+ const target = useMemo5(() => matchRoute(location.pathname), [location.pathname, matchRoute]);
1480
1809
  const params = target?.params || {};
1481
- const searchParams = useMemo4(() => new URLSearchParams(location.search), [location.search]);
1482
- const navigate = useCallback4((to, options = {}) => {
1810
+ const searchParams = useMemo5(() => new URLSearchParams(location.search), [location.search]);
1811
+ const navigate = useCallback5((to, options = {}) => {
1483
1812
  navigateInternal(to, options);
1484
1813
  }, []);
1485
1814
  useEffect4(() => {
@@ -1656,7 +1985,7 @@ function RouterProvider({
1656
1985
  }
1657
1986
  };
1658
1987
  }, [target, pathname, matchRoute]);
1659
- const notFoundResolver = useCallback4((pathname2) => {
1988
+ const notFoundResolver = useCallback5((pathname2) => {
1660
1989
  try {
1661
1990
  const list = Array.isArray(notFoundRoutes) ? notFoundRoutes : [];
1662
1991
  let chosen;
@@ -1676,7 +2005,7 @@ function RouterProvider({
1676
2005
  return;
1677
2006
  }
1678
2007
  }, [notFoundRoutes]);
1679
- const contextValue = useMemo4(() => ({
2008
+ const contextValue = useMemo5(() => ({
1680
2009
  pathname: location.pathname,
1681
2010
  params,
1682
2011
  searchParams,
@@ -1693,7 +2022,7 @@ function RouterProvider({
1693
2022
  matchRoute,
1694
2023
  notFoundResolver
1695
2024
  ]);
1696
- const matchingLayouts = useMemo4(() => {
2025
+ const matchingLayouts = useMemo5(() => {
1697
2026
  return layouts.filter((layout) => {
1698
2027
  if (layout.pattern === "/")
1699
2028
  return true;
@@ -1705,25 +2034,25 @@ function RouterProvider({
1705
2034
  let content;
1706
2035
  if (target) {
1707
2036
  const Component = target.route.component;
1708
- let outletContent = /* @__PURE__ */ jsx3(Component, {});
2037
+ let outletContent = /* @__PURE__ */ jsx4(Component, {});
1709
2038
  for (let i = matchingLayouts.length - 1;i >= 0; i--) {
1710
2039
  const Layout = matchingLayouts[i].component;
1711
2040
  const currentOutlet = outletContent;
1712
- outletContent = /* @__PURE__ */ jsx3(OutletContext.Provider, {
2041
+ outletContent = /* @__PURE__ */ jsx4(OutletContext.Provider, {
1713
2042
  value: currentOutlet,
1714
- children: /* @__PURE__ */ jsx3(Layout, {})
2043
+ children: /* @__PURE__ */ jsx4(Layout, {})
1715
2044
  });
1716
2045
  }
1717
2046
  content = outletContent;
1718
2047
  } else {
1719
2048
  const Fallback = notFoundResolver(location.pathname) || NotFound;
1720
2049
  if (Fallback) {
1721
- content = /* @__PURE__ */ jsx3(Fallback, {});
2050
+ content = /* @__PURE__ */ jsx4(Fallback, {});
1722
2051
  } else {
1723
2052
  content = /* @__PURE__ */ jsxs("div", {
1724
2053
  style: { padding: "2rem", textAlign: "center" },
1725
2054
  children: [
1726
- /* @__PURE__ */ jsx3("h1", {
2055
+ /* @__PURE__ */ jsx4("h1", {
1727
2056
  children: "404 - Page Not Found"
1728
2057
  }),
1729
2058
  /* @__PURE__ */ jsxs("p", {
@@ -1733,7 +2062,7 @@ function RouterProvider({
1733
2062
  " could not be found."
1734
2063
  ]
1735
2064
  }),
1736
- /* @__PURE__ */ jsx3("a", {
2065
+ /* @__PURE__ */ jsx4("a", {
1737
2066
  href: "/",
1738
2067
  children: "Go Home"
1739
2068
  })
@@ -1741,14 +2070,22 @@ function RouterProvider({
1741
2070
  });
1742
2071
  }
1743
2072
  }
1744
- return /* @__PURE__ */ jsx3(RouterContext.Provider, {
2073
+ return /* @__PURE__ */ jsx4(RouterContext.Provider, {
1745
2074
  value: contextValue,
1746
2075
  children: children || content
1747
2076
  });
1748
2077
  }
1749
2078
 
1750
2079
  // packages/react/src/providers/RerouteProvider.tsx
1751
- 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
+ }
1752
2089
  function RerouteProvider({
1753
2090
  byCollection,
1754
2091
  getContentEntry,
@@ -1763,30 +2100,51 @@ function RerouteProvider({
1763
2100
  viewTransitions,
1764
2101
  scrollRestoration,
1765
2102
  markdownComponents,
2103
+ i18n: i18nProp,
1766
2104
  children
1767
2105
  }) {
1768
2106
  const loader = loadContent || (contentBaseUrl ? (c) => import(`${contentBaseUrl}/${c}.js`) : undefined);
1769
- return /* @__PURE__ */ jsx4(ContentProvider, {
1770
- getEntry: getContentEntry,
1771
- byCollection: byCollection || null,
1772
- loadCollection: loader,
1773
- markdownComponents,
1774
- children: /* @__PURE__ */ jsx4(RouterProvider, {
1775
- layouts,
1776
- matchRoute,
1777
- notFoundRoutes,
1778
- notFound,
1779
- pathname,
1780
- searchParams,
1781
- viewTransitions,
1782
- scrollRestoration,
1783
- 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
+ })
1784
2142
  })
1785
2143
  });
1786
2144
  }
1787
2145
  // packages/react/src/hooks/useRouter.tsx
1788
2146
  function useRouter() {
1789
- const context = useContext2(RouterContext);
2147
+ const context = useContext3(RouterContext);
1790
2148
  if (!context) {
1791
2149
  throw new Error("useRouter must be used within a RouterProvider");
1792
2150
  }
@@ -2007,7 +2365,7 @@ function useData(key) {
2007
2365
  pending[pathToFetch] = fetchPromise;
2008
2366
  } catch {}
2009
2367
  }, [k, pathname]);
2010
- return useMemo5(() => {
2368
+ return useMemo7(() => {
2011
2369
  try {
2012
2370
  const source = typeof window === "undefined" ? globalThis.__REROUTE_DATA__ : window.__REROUTE_DATA__;
2013
2371
  let value = source?.[k];
@@ -2172,10 +2530,10 @@ function useData(key) {
2172
2530
  }, [k, _tick, pathname]);
2173
2531
  }
2174
2532
  // packages/react/src/hooks/useFeed.ts
2175
- import { useMemo as useMemo6 } from "react";
2533
+ import { useMemo as useMemo8 } from "react";
2176
2534
  function useFeed() {
2177
2535
  const { pathname } = useRouter();
2178
- return useMemo6(() => {
2536
+ return useMemo8(() => {
2179
2537
  const availableFeeds = typeof globalThis !== "undefined" ? globalThis.__REROUTE_AVAILABLE_FEEDS__ || globalThis.__REROUTE_FEEDS__ || [] : [];
2180
2538
  const parts = pathname.split("/").filter(Boolean);
2181
2539
  const mainFeedUrl = "/feed.xml";
@@ -2203,7 +2561,7 @@ function useFeed() {
2203
2561
  }, [pathname]);
2204
2562
  }
2205
2563
  // packages/react/src/hooks/useLayoutData.ts
2206
- 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";
2207
2565
  var isThenable2 = (value) => {
2208
2566
  return typeof value === "object" && value !== null && typeof value.then === "function";
2209
2567
  };
@@ -2218,7 +2576,7 @@ var isInitialHydration2 = () => {
2218
2576
  function useLayoutData() {
2219
2577
  const { pathname } = useRouter();
2220
2578
  const [_tick, setTick] = useState6(0);
2221
- const layoutKey = useMemo7(() => {
2579
+ const layoutKey = useMemo9(() => {
2222
2580
  const parts = pathname.split("/").filter(Boolean);
2223
2581
  if (parts.length === 0)
2224
2582
  return "__layout:/";
@@ -2307,7 +2665,7 @@ function useLayoutData() {
2307
2665
  });
2308
2666
  } catch {}
2309
2667
  }, [layoutKey, pathname]);
2310
- return useMemo7(() => {
2668
+ return useMemo9(() => {
2311
2669
  try {
2312
2670
  const source = typeof window === "undefined" ? globalThis.__REROUTE_DATA__ : window.__REROUTE_DATA__;
2313
2671
  let value = source?.[layoutKey];
@@ -2365,10 +2723,10 @@ function useLayoutData() {
2365
2723
  }, [layoutKey, _tick]);
2366
2724
  }
2367
2725
  // packages/react/src/hooks/useLlms.ts
2368
- import { useMemo as useMemo8 } from "react";
2726
+ import { useMemo as useMemo10 } from "react";
2369
2727
  function useLlms() {
2370
2728
  const { pathname } = useRouter();
2371
- return useMemo8(() => {
2729
+ return useMemo10(() => {
2372
2730
  const availableLlms = typeof globalThis !== "undefined" ? globalThis.__REROUTE_AVAILABLE_LLMS__ || globalThis.__REROUTE_LLMS__ || [] : [];
2373
2731
  const parts = pathname.split("/").filter(Boolean);
2374
2732
  const mainLlmsUrl = "/llms.txt";
@@ -2492,7 +2850,16 @@ function useToc() {
2492
2850
  return { toc, isLoading: false };
2493
2851
  }
2494
2852
  // packages/react/src/components/ContentRoute.tsx
2495
- 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
+ }
2496
2863
  function getCapturedHtml(key) {
2497
2864
  try {
2498
2865
  const g = globalThis;
@@ -2516,26 +2883,33 @@ function ContentRoute({
2516
2883
  const params = useParams();
2517
2884
  const router = useRouter();
2518
2885
  const { pathname, notFoundResolver } = router;
2519
- const inferredName = name || params.slug || params.name || (() => {
2886
+ const { locale, defaultLocale, enabled: i18nEnabled } = useLocale();
2887
+ const pathInfo = (() => {
2520
2888
  try {
2521
2889
  const parts = String(pathname || "").split("/").filter(Boolean);
2522
- return parts.length >= 2 ? parts[1] : undefined;
2523
- } catch {
2524
- return;
2525
- }
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 };
2526
2898
  })();
2527
- 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}:`;
2528
2902
  const ctxGetEntry = useContentGetEntry();
2529
2903
  const idx = useContentIndex();
2530
2904
  const ensureCollection = useContentLoadCollection();
2531
2905
  const markdownComponents = useMarkdownComponents();
2532
2906
  const resolved404 = notFoundResolver ? notFoundResolver(pathname) : undefined;
2533
- const resolveEntry = getEntry || ctxGetEntry || ((c, n) => {
2907
+ const resolveEntry = getEntry || ctxGetEntry || ((c, n, loc) => {
2534
2908
  try {
2535
2909
  const list = idx?.[c];
2536
2910
  if (!Array.isArray(list))
2537
2911
  return;
2538
- 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);
2539
2913
  if (!found)
2540
2914
  return;
2541
2915
  return {
@@ -2547,8 +2921,8 @@ function ContentRoute({
2547
2921
  return;
2548
2922
  }
2549
2923
  });
2550
- const entry = inferredName && resolveEntry ? resolveEntry(collection, inferredName) : undefined;
2551
- const initialComp = useMemo9(() => {
2924
+ const entry = inferredName && resolveEntry ? resolveEntry(collection, inferredName, activeLocale) : undefined;
2925
+ const initialComp = useMemo11(() => {
2552
2926
  try {
2553
2927
  const g = globalThis;
2554
2928
  const mod = g.__REROUTE_SSR_MODULES__?.[key];
@@ -2558,8 +2932,8 @@ function ContentRoute({
2558
2932
  }
2559
2933
  } catch {}
2560
2934
  if (typeof window !== "undefined") {
2561
- const store = window.__REROUTE_MODULES__ || {};
2562
- const cached = store[key];
2935
+ const store2 = window.__REROUTE_MODULES__ || {};
2936
+ const cached = store2[key];
2563
2937
  if (cached) {
2564
2938
  const C = cached.default || cached;
2565
2939
  return toComponent(C);
@@ -2582,8 +2956,8 @@ function ContentRoute({
2582
2956
  if (g.__REROUTE_SSR_MODULES__?.[key]) {
2583
2957
  hasInitialContent = true;
2584
2958
  } else if (typeof window !== "undefined") {
2585
- const store = window.__REROUTE_MODULES__ || {};
2586
- if (store[key]) {
2959
+ const store2 = window.__REROUTE_MODULES__ || {};
2960
+ if (store2[key]) {
2587
2961
  hasInitialContent = true;
2588
2962
  }
2589
2963
  } else if (entry?.component) {
@@ -2714,11 +3088,11 @@ function ContentRoute({
2714
3088
  const compProps = markdownComponents ? { components: markdownComponents } : {};
2715
3089
  const isServer = typeof window === "undefined";
2716
3090
  if (isServer) {
2717
- return /* @__PURE__ */ jsx5("div", {
3091
+ return /* @__PURE__ */ jsx6("div", {
2718
3092
  "data-reroute": "content",
2719
3093
  "data-reroute-key": key,
2720
3094
  ref: containerRef,
2721
- children: /* @__PURE__ */ jsx5(Comp, {
3095
+ children: /* @__PURE__ */ jsx6(Comp, {
2722
3096
  ...compProps
2723
3097
  })
2724
3098
  });
@@ -2726,18 +3100,18 @@ function ContentRoute({
2726
3100
  const capturedHtml = getCapturedHtml(key);
2727
3101
  const hasLoadedModule = !!globalThis.__REROUTE_SSR_MODULES__?.[key] || !!globalThis.__REROUTE_MODULES__?.[key];
2728
3102
  if (capturedHtml && !hasLoadedModule) {
2729
- return /* @__PURE__ */ jsx5("div", {
3103
+ return /* @__PURE__ */ jsx6("div", {
2730
3104
  "data-reroute": "content",
2731
3105
  "data-reroute-key": key,
2732
3106
  ref: containerRef,
2733
3107
  dangerouslySetInnerHTML: { __html: capturedHtml }
2734
3108
  });
2735
3109
  }
2736
- return /* @__PURE__ */ jsx5("div", {
3110
+ return /* @__PURE__ */ jsx6("div", {
2737
3111
  "data-reroute": "content",
2738
3112
  "data-reroute-key": key,
2739
3113
  ref: containerRef,
2740
- children: /* @__PURE__ */ jsx5(Comp, {
3114
+ children: /* @__PURE__ */ jsx6(Comp, {
2741
3115
  ...compProps
2742
3116
  })
2743
3117
  });
@@ -2748,7 +3122,7 @@ import {
2748
3122
  useRef as useRef2,
2749
3123
  useState as useState9
2750
3124
  } from "react";
2751
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
3125
+ import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
2752
3126
  var DEFAULT_DEVICE_SIZES = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
2753
3127
  function generateSrcSet(src, width, quality, format, loader) {
2754
3128
  const sizes = width ? DEFAULT_DEVICE_SIZES.filter((size) => size <= width * 2) : DEFAULT_DEVICE_SIZES;
@@ -2905,7 +3279,7 @@ function Image({
2905
3279
  height: "100%"
2906
3280
  },
2907
3281
  children: [
2908
- showSpinner && !isLoaded && !hasError && /* @__PURE__ */ jsx6("span", {
3282
+ showSpinner && !isLoaded && !hasError && /* @__PURE__ */ jsx7("span", {
2909
3283
  style: {
2910
3284
  position: "absolute",
2911
3285
  inset: 0,
@@ -2916,7 +3290,7 @@ function Image({
2916
3290
  zIndex: 1,
2917
3291
  pointerEvents: "none"
2918
3292
  },
2919
- children: spinner || /* @__PURE__ */ jsx6("span", {
3293
+ children: spinner || /* @__PURE__ */ jsx7("span", {
2920
3294
  style: {
2921
3295
  display: "block",
2922
3296
  width: `${spinnerSize}px`,
@@ -2928,7 +3302,7 @@ function Image({
2928
3302
  }
2929
3303
  })
2930
3304
  }),
2931
- placeholder === "blur" && placeholderSrc && !isLoaded && !hasError && /* @__PURE__ */ jsx6("img", {
3305
+ placeholder === "blur" && placeholderSrc && !isLoaded && !hasError && /* @__PURE__ */ jsx7("img", {
2932
3306
  src: placeholderSrc,
2933
3307
  draggable,
2934
3308
  alt: "",
@@ -2944,7 +3318,7 @@ function Image({
2944
3318
  zIndex: -1
2945
3319
  }
2946
3320
  }),
2947
- /* @__PURE__ */ jsx6("img", {
3321
+ /* @__PURE__ */ jsx7("img", {
2948
3322
  ref: imgRef,
2949
3323
  draggable,
2950
3324
  src: priority || supportsNativeLazyLoading() ? imageUrl : undefined,
@@ -2963,7 +3337,7 @@ function Image({
2963
3337
  className,
2964
3338
  ...props
2965
3339
  }),
2966
- showSpinner && !isLoaded && /* @__PURE__ */ jsx6("style", {
3340
+ showSpinner && !isLoaded && /* @__PURE__ */ jsx7("style", {
2967
3341
  children: `
2968
3342
  @keyframes reroute-spin {
2969
3343
  0% { transform: rotate(0deg); }
@@ -2973,7 +3347,7 @@ function Image({
2973
3347
  })
2974
3348
  ]
2975
3349
  }),
2976
- showCaption && /* @__PURE__ */ jsx6("em", {
3350
+ showCaption && /* @__PURE__ */ jsx7("em", {
2977
3351
  style: {
2978
3352
  display: "block",
2979
3353
  fontSize: "75%",
@@ -2989,8 +3363,8 @@ function Image({
2989
3363
  });
2990
3364
  }
2991
3365
  // packages/react/src/components/Link.tsx
2992
- import { useCallback as useCallback5, useContext as useContext3, useMemo as useMemo10 } from "react";
2993
- 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";
2994
3368
  function parseLocalUrl(to) {
2995
3369
  if (typeof window === "undefined")
2996
3370
  return null;
@@ -3030,35 +3404,35 @@ function dispatchDataEvent(detail) {
3030
3404
  function storeAndDispatchData(path, payload, silent = false) {
3031
3405
  if (!payload || typeof payload !== "object")
3032
3406
  return;
3033
- const store = getRerouteDataStore();
3407
+ const store2 = getRerouteDataStore();
3034
3408
  if (payload.__reroute_multiple__ === true) {
3035
3409
  const keys = Object.keys(payload).filter((k) => k !== "__reroute_multiple__");
3036
3410
  for (const key of keys) {
3037
- store[key] = payload[key];
3411
+ store2[key] = payload[key];
3038
3412
  }
3039
3413
  if (!silent)
3040
3414
  dispatchDataEvent({ keys });
3041
3415
  } else if (payload.__flatten__ === true || payload.__reroute_flattened__ === true) {
3042
3416
  const keys = Object.keys(payload).filter((k) => k !== "__flatten__" && k !== "__reroute_flattened__");
3043
3417
  for (const key of keys) {
3044
- store[key] = payload[key];
3418
+ store2[key] = payload[key];
3045
3419
  }
3046
- store[path] = payload;
3420
+ store2[path] = payload;
3047
3421
  if (!silent)
3048
3422
  dispatchDataEvent({ keys: [...keys, path] });
3049
3423
  } else {
3050
- store[path] = payload;
3424
+ store2[path] = payload;
3051
3425
  if (!silent)
3052
3426
  dispatchDataEvent({ key: path });
3053
3427
  }
3054
3428
  }
3055
3429
  function needsDataPrefetch(path, inferred, matchRoute) {
3056
3430
  const isDynamic = !!matchRoute?.(path)?.route?.isDynamic;
3057
- const store = getRerouteDataStore();
3431
+ const store2 = getRerouteDataStore();
3058
3432
  const hasRealContent = inferred?.module !== undefined;
3059
3433
  if (hasRealContent)
3060
3434
  return false;
3061
- if (store[path] !== undefined)
3435
+ if (store2[path] !== undefined)
3062
3436
  return false;
3063
3437
  const route = matchRoute?.(path)?.route;
3064
3438
  const hasSSRData = !!(route?.ssr && typeof route.ssr === "object" && typeof route.ssr.data === "function");
@@ -3135,18 +3509,20 @@ function Link({
3135
3509
  draggable = false,
3136
3510
  ...props
3137
3511
  }) {
3138
- const routerContext = useContext3(RouterContext);
3512
+ const routerContext = useContext4(RouterContext);
3139
3513
  const router = useRouter();
3140
3514
  const resolver = useContentResolver();
3141
3515
  const contentIndex = useContentIndex();
3142
3516
  const ensureCollection = useContentLoadCollection();
3517
+ const { localizePath, enabled: i18nEnabled } = useLocaleContext();
3143
3518
  const hasRouter = !!routerContext;
3144
3519
  const { navigate, matchRoute } = router || {
3145
3520
  navigate: () => {},
3146
3521
  matchRoute: () => null
3147
3522
  };
3148
- const inferred = useMemo10(() => resolver ? resolver(String(to)) : undefined, [resolver, to]);
3149
- 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) => {
3150
3526
  const currentPath = window.location.pathname + window.location.search;
3151
3527
  if (localUrl.fullPath !== currentPath)
3152
3528
  return false;
@@ -3157,14 +3533,17 @@ function Link({
3157
3533
  if (element) {
3158
3534
  element.scrollIntoView({ behavior: "smooth" });
3159
3535
  } else {
3160
- navigate(fragment ? `${to}#${fragment}` : to, { replace, state });
3536
+ navigate(fragment ? `${resolvedTo}#${fragment}` : resolvedTo, {
3537
+ replace,
3538
+ state
3539
+ });
3161
3540
  }
3162
3541
  } else {
3163
3542
  window.scrollTo({ top: 0, behavior: "smooth" });
3164
3543
  }
3165
3544
  return true;
3166
- }, [fragment, navigate, replace, state, to]);
3167
- const triggerPrefetch = useCallback5((localUrl, options) => {
3545
+ }, [fragment, navigate, replace, state, resolvedTo]);
3546
+ const triggerPrefetch = useCallback7((localUrl, options) => {
3168
3547
  if (needsDataPrefetch(localUrl.path, inferred, matchRoute)) {
3169
3548
  if (options?.withTimeout) {
3170
3549
  prefetchRouteDataWithTimeout(localUrl.path);
@@ -3177,27 +3556,30 @@ function Link({
3177
3556
  prefetchContentModule(inferred, contentIndex, ensureCollection);
3178
3557
  }
3179
3558
  }, [inferred, ensureCollection, contentIndex, matchRoute]);
3180
- const handleClick = useCallback5(async (e) => {
3559
+ const handleClick = useCallback7(async (e) => {
3181
3560
  onClick?.(e);
3182
3561
  if (!hasRouter)
3183
3562
  return;
3184
3563
  if (isModifiedClick(e, props.target))
3185
3564
  return;
3186
- if (shouldSkipInterception(String(to)))
3565
+ if (shouldSkipInterception(resolvedTo))
3187
3566
  return;
3188
3567
  e.preventDefault();
3189
- const localUrl = parseLocalUrl(String(to));
3568
+ const localUrl = parseLocalUrl(resolvedTo);
3190
3569
  if (localUrl && handleSameRouteNavigation(localUrl))
3191
3570
  return;
3192
3571
  if (prefetch && localUrl) {
3193
3572
  await triggerPrefetch(localUrl, { withTimeout: true });
3194
3573
  }
3195
- navigate(fragment ? `${to}#${fragment}` : to, { replace, state });
3574
+ navigate(fragment ? `${resolvedTo}#${fragment}` : resolvedTo, {
3575
+ replace,
3576
+ state
3577
+ });
3196
3578
  }, [
3197
3579
  onClick,
3198
3580
  hasRouter,
3199
3581
  props.target,
3200
- to,
3582
+ resolvedTo,
3201
3583
  handleSameRouteNavigation,
3202
3584
  prefetch,
3203
3585
  triggerPrefetch,
@@ -3206,24 +3588,24 @@ function Link({
3206
3588
  replace,
3207
3589
  state
3208
3590
  ]);
3209
- const handleMouseEnter = useCallback5((e) => {
3591
+ const handleMouseEnter = useCallback7((e) => {
3210
3592
  if (prefetch) {
3211
- const localUrl = parseLocalUrl(String(to));
3593
+ const localUrl = parseLocalUrl(resolvedTo);
3212
3594
  if (localUrl)
3213
3595
  triggerPrefetch(localUrl, { silent: true });
3214
3596
  }
3215
3597
  onMouseEnter?.(e);
3216
- }, [prefetch, to, triggerPrefetch, onMouseEnter]);
3217
- const handleFocus = useCallback5((e) => {
3598
+ }, [prefetch, resolvedTo, triggerPrefetch, onMouseEnter]);
3599
+ const handleFocus = useCallback7((e) => {
3218
3600
  if (prefetch) {
3219
- const localUrl = parseLocalUrl(String(to));
3601
+ const localUrl = parseLocalUrl(resolvedTo);
3220
3602
  if (localUrl)
3221
3603
  triggerPrefetch(localUrl, { silent: true });
3222
3604
  }
3223
3605
  onFocus?.(e);
3224
- }, [prefetch, to, triggerPrefetch, onFocus]);
3225
- const href = fragment ? `${to}#${fragment}` : to;
3226
- return /* @__PURE__ */ jsx7("a", {
3606
+ }, [prefetch, resolvedTo, triggerPrefetch, onFocus]);
3607
+ const href = fragment ? `${resolvedTo}#${fragment}` : resolvedTo;
3608
+ return /* @__PURE__ */ jsx8("a", {
3227
3609
  href,
3228
3610
  onClick: handleClick,
3229
3611
  onMouseEnter: handleMouseEnter,
@@ -3234,7 +3616,7 @@ function Link({
3234
3616
  }
3235
3617
  // packages/react/src/components/Markdown.tsx
3236
3618
  import { Streamdown } from "streamdown";
3237
- import { jsx as jsx8 } from "react/jsx-runtime";
3619
+ import { jsx as jsx9 } from "react/jsx-runtime";
3238
3620
  function Markdown({
3239
3621
  children,
3240
3622
  className,
@@ -3244,9 +3626,9 @@ function Markdown({
3244
3626
  }) {
3245
3627
  const finalRemarkPlugins = [...remarkPlugins];
3246
3628
  const finalRehypePlugins = [...rehypePlugins];
3247
- return /* @__PURE__ */ jsx8("div", {
3629
+ return /* @__PURE__ */ jsx9("div", {
3248
3630
  className,
3249
- children: /* @__PURE__ */ jsx8(Streamdown, {
3631
+ children: /* @__PURE__ */ jsx9(Streamdown, {
3250
3632
  remarkPlugins: finalRemarkPlugins,
3251
3633
  rehypePlugins: finalRehypePlugins,
3252
3634
  components,
@@ -3255,11 +3637,11 @@ function Markdown({
3255
3637
  });
3256
3638
  }
3257
3639
  // packages/react/src/components/Outlet.tsx
3258
- import { useContext as useContext4 } from "react";
3259
- 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";
3260
3642
  function Outlet() {
3261
- const outletContent = useContext4(OutletContext);
3262
- return /* @__PURE__ */ jsx9(Fragment2, {
3643
+ const outletContent = useContext5(OutletContext);
3644
+ return /* @__PURE__ */ jsx10(Fragment2, {
3263
3645
  children: outletContent
3264
3646
  });
3265
3647
  }
@@ -3278,7 +3660,7 @@ async function collectionSearch(options) {
3278
3660
  return null;
3279
3661
  const indexData = JSON.parse(await file.text());
3280
3662
  const entries = indexData.entries || [];
3281
- const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 1);
3663
+ const terms = query.toLowerCase().split(/\s+/).filter((t2) => t2.length > 1);
3282
3664
  if (terms.length === 0)
3283
3665
  return null;
3284
3666
  const collectionsFilter = searchParams?.get("collections")?.split(",").filter(Boolean);
@@ -3366,6 +3748,8 @@ export {
3366
3748
  useParams,
3367
3749
  useNavigate,
3368
3750
  useMarkdownComponents,
3751
+ useLocaleContext,
3752
+ useLocale,
3369
3753
  useLlms,
3370
3754
  useLayoutData,
3371
3755
  useFeed,
@@ -3375,6 +3759,7 @@ export {
3375
3759
  useContentIndex,
3376
3760
  useContentGetEntry,
3377
3761
  useContent,
3762
+ t,
3378
3763
  storeAndDispatchData,
3379
3764
  shouldSkipInterception,
3380
3765
  preloadRoute,
@@ -3383,12 +3768,16 @@ export {
3383
3768
  prefetchContentModule,
3384
3769
  prefetchContent,
3385
3770
  parseLocalUrl,
3771
+ parseContentPath,
3386
3772
  parseContentHref,
3387
3773
  needsDataPrefetch,
3774
+ localizeHref,
3775
+ localizeContentHref,
3388
3776
  isModifiedClick,
3389
3777
  getRerouteDataStore,
3390
3778
  fetchRouteData,
3391
3779
  dispatchDataEvent,
3780
+ createTranslator,
3392
3781
  createResolverFromGetEntry,
3393
3782
  createLazyRoute,
3394
3783
  collectionSearch,
@@ -3402,6 +3791,7 @@ export {
3402
3791
  OutletContext,
3403
3792
  Outlet,
3404
3793
  Markdown,
3794
+ LocaleProvider,
3405
3795
  Link,
3406
3796
  Image,
3407
3797
  ContentRoute,
@@ -3409,4 +3799,4 @@ export {
3409
3799
  ClientOnly
3410
3800
  };
3411
3801
 
3412
- //# debugId=3A24E3C6448E590164756E2164756E21
3802
+ //# debugId=C69A90B48CACDDC864756E2164756E21