@rangojs/router 0.5.1 → 0.6.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 (609) hide show
  1. package/README.md +5 -1
  2. package/dist/bin/rango.js +343 -125
  3. package/dist/types/browser/event-controller.d.ts +6 -0
  4. package/dist/types/browser/react/use-router.d.ts +10 -3
  5. package/dist/types/browser/react/use-search-params.d.ts +57 -10
  6. package/dist/types/browser/types.d.ts +22 -0
  7. package/dist/types/build/merge-full-manifests.d.ts +3 -0
  8. package/dist/types/build/route-trie.d.ts +4 -73
  9. package/dist/types/build/route-types/per-module-writer.d.ts +6 -4
  10. package/dist/types/build/route-types/router-processing.d.ts +2 -3
  11. package/dist/types/cache/cache-exec-scope.d.ts +31 -0
  12. package/dist/types/cache/cf/cf-cache-constants.d.ts +8 -1
  13. package/dist/types/cache/cf/cf-cache-store.d.ts +15 -1
  14. package/dist/types/cache/cf/cf-cache-types.d.ts +1 -1
  15. package/dist/types/cache/cf/cf-kv-utils.d.ts +21 -0
  16. package/dist/types/cache/taint.d.ts +12 -6
  17. package/dist/types/client-urls/client-root.d.ts +38 -0
  18. package/dist/types/client-urls/client-urls.d.ts +5 -0
  19. package/dist/types/client-urls/navigation.d.ts +38 -0
  20. package/dist/types/client-urls/revalidation-protocol.d.ts +25 -0
  21. package/dist/types/client-urls/server-projection.d.ts +62 -0
  22. package/dist/types/client-urls/types.d.ts +144 -0
  23. package/dist/types/client.d.ts +12 -4
  24. package/dist/types/client.rsc.d.ts +4 -1
  25. package/dist/types/decode-loader-results.d.ts +37 -0
  26. package/dist/types/errors.d.ts +1 -0
  27. package/dist/types/handles/is-thenable.d.ts +2 -4
  28. package/dist/types/index.d.ts +1 -1
  29. package/dist/types/loader-redirect.d.ts +27 -0
  30. package/dist/types/outlet-context.d.ts +12 -0
  31. package/dist/types/outlet-provider.d.ts +3 -1
  32. package/dist/types/redirect-origin.d.ts +4 -0
  33. package/dist/types/route-content-wrapper.d.ts +42 -1
  34. package/dist/types/route-definition/helpers-types.d.ts +13 -2
  35. package/dist/types/router/error-handling.d.ts +35 -1
  36. package/dist/types/router/intercept-resolution.d.ts +12 -0
  37. package/dist/types/router/loader-resolution.d.ts +24 -2
  38. package/dist/types/router/revalidation.d.ts +7 -0
  39. package/dist/{types.backup/build/route-trie.d.ts → types/router/route-trie-builder.d.ts} +4 -16
  40. package/dist/types/router/router-interfaces.d.ts +20 -0
  41. package/dist/types/router/segment-resolution/helpers.d.ts +1 -1
  42. package/dist/types/router/trie-matching.d.ts +1 -1
  43. package/dist/types/rsc/helpers.d.ts +3 -0
  44. package/dist/types/rsc/manifest-init.d.ts +5 -5
  45. package/dist/types/rsc/render-pipeline.d.ts +9 -0
  46. package/dist/types/rsc/routine-plan.d.ts +124 -0
  47. package/dist/types/rsc/shell-capture-constants.d.ts +17 -0
  48. package/dist/types/rsc/shell-capture.d.ts +9 -0
  49. package/dist/types/rsc/shell-serve.d.ts +11 -0
  50. package/dist/types/rsc/types.d.ts +30 -0
  51. package/dist/types/segment-system.d.ts +2 -0
  52. package/dist/types/server/context.d.ts +10 -0
  53. package/dist/types/server/handle-store.d.ts +34 -3
  54. package/dist/types/server/request-context.d.ts +14 -1
  55. package/dist/types/server.d.ts +1 -0
  56. package/dist/types/ssr/index.d.ts +22 -0
  57. package/dist/types/ssr/ssr-root.d.ts +10 -0
  58. package/dist/types/testing/dom.entry.d.ts +1 -1
  59. package/dist/types/testing/render-route.d.ts +16 -6
  60. package/dist/types/testing/run-loader.d.ts +9 -0
  61. package/dist/types/types/boundaries.d.ts +22 -0
  62. package/dist/types/types/index.d.ts +1 -1
  63. package/dist/types/types/loader-types.d.ts +57 -5
  64. package/dist/types/types/segments.d.ts +7 -0
  65. package/dist/types/urls/path-helper-types.d.ts +10 -4
  66. package/dist/types/vite/discovery/client-urls-projection.d.ts +53 -0
  67. package/dist/types/vite/discovery/discover-routers.d.ts +1 -1
  68. package/dist/types/vite/discovery/state.d.ts +8 -1
  69. package/dist/types/vite/encryption-key.d.ts +2 -0
  70. package/dist/types/vite/plugins/expose-internal-ids.d.ts +10 -0
  71. package/dist/types/vite/plugins/server-ref-hashing.d.ts +24 -0
  72. package/dist/types/vite/plugins/server-reference-pattern.d.ts +1 -0
  73. package/dist/types/vite/utils/shared-utils.d.ts +12 -0
  74. package/dist/vite/index.js +5101 -2056
  75. package/package.json +3 -3
  76. package/skills/breadcrumbs/SKILL.md +39 -9
  77. package/skills/caching/SKILL.md +1 -1
  78. package/skills/catalog.json +7 -1
  79. package/skills/client-urls/SKILL.md +338 -0
  80. package/skills/comparison/references/framework-comparison.md +23 -9
  81. package/skills/hooks/SKILL.md +2 -2
  82. package/skills/hooks/data.md +11 -2
  83. package/skills/hooks/handle-and-actions.md +7 -0
  84. package/skills/hooks/outlets.md +26 -5
  85. package/skills/hooks/urls.md +40 -3
  86. package/skills/loader/SKILL.md +132 -20
  87. package/skills/migrate-nextjs/SKILL.md +70 -10
  88. package/skills/migrate-react-router/SKILL.md +49 -13
  89. package/skills/migrate-react-router/component-migration.md +18 -13
  90. package/skills/migrate-react-router/data-and-actions.md +14 -3
  91. package/skills/migrate-react-router/route-mapping.md +15 -2
  92. package/skills/mime-routes/SKILL.md +3 -1
  93. package/skills/parallel/SKILL.md +32 -1
  94. package/skills/ppr/SKILL.md +16 -6
  95. package/skills/prerender/SKILL.md +8 -4
  96. package/skills/rango/SKILL.md +21 -17
  97. package/skills/react-compiler/SKILL.md +3 -3
  98. package/skills/response-routes/SKILL.md +4 -2
  99. package/skills/route/SKILL.md +5 -2
  100. package/skills/router-setup/SKILL.md +16 -2
  101. package/skills/scripts/SKILL.md +16 -6
  102. package/skills/shell-manifest/SKILL.md +16 -7
  103. package/skills/testing/SKILL.md +2 -2
  104. package/skills/testing/client-components.md +6 -0
  105. package/skills/testing/handles.md +30 -8
  106. package/skills/testing/loader.md +51 -49
  107. package/skills/testing/middleware.md +1 -1
  108. package/skills/theme/SKILL.md +8 -5
  109. package/skills/typesafety/generated-files-and-cli.md +16 -9
  110. package/skills/typesafety/route-types.md +5 -1
  111. package/skills/use-cache/SKILL.md +47 -0
  112. package/src/bin/rango.ts +7 -3
  113. package/src/browser/event-controller.ts +40 -15
  114. package/src/browser/navigation-bridge.ts +6 -0
  115. package/src/browser/navigation-client.ts +5 -0
  116. package/src/browser/partial-update.ts +77 -10
  117. package/src/browser/react/NavigationProvider.tsx +7 -0
  118. package/src/browser/react/use-router.ts +40 -11
  119. package/src/browser/react/use-search-params.ts +140 -17
  120. package/src/browser/rsc-router.tsx +59 -0
  121. package/src/browser/server-action-bridge.ts +26 -0
  122. package/src/browser/types.ts +22 -0
  123. package/src/build/merge-full-manifests.ts +161 -0
  124. package/src/build/route-trie.ts +9 -332
  125. package/src/build/route-types/include-resolution.ts +66 -11
  126. package/src/build/route-types/per-module-writer.ts +11 -6
  127. package/src/build/route-types/router-processing.ts +184 -153
  128. package/src/build/runtime-discovery.ts +23 -12
  129. package/src/cache/cache-exec-scope.ts +47 -0
  130. package/src/cache/cache-runtime.ts +113 -40
  131. package/src/cache/cf/cf-cache-constants.ts +8 -1
  132. package/src/cache/cf/cf-cache-store.ts +41 -64
  133. package/src/cache/cf/cf-cache-types.ts +1 -1
  134. package/src/cache/cf/cf-kv-utils.ts +38 -0
  135. package/src/cache/segment-codec.ts +21 -5
  136. package/src/cache/taint.ts +28 -9
  137. package/src/client-urls/client-root.tsx +168 -0
  138. package/src/client-urls/client-urls.ts +698 -0
  139. package/src/client-urls/navigation.ts +237 -0
  140. package/src/client-urls/revalidation-protocol.ts +56 -0
  141. package/src/client-urls/server-projection.ts +579 -0
  142. package/src/client-urls/types.ts +195 -0
  143. package/src/client.rsc.tsx +12 -0
  144. package/src/client.tsx +49 -6
  145. package/src/decode-loader-results.ts +113 -0
  146. package/src/errors.ts +14 -0
  147. package/src/handles/deferred-resolution.ts +14 -7
  148. package/src/handles/is-thenable.ts +2 -4
  149. package/src/index.ts +1 -0
  150. package/src/loader-redirect.tsx +64 -0
  151. package/src/outlet-context.ts +12 -0
  152. package/src/outlet-provider.tsx +15 -1
  153. package/src/redirect-origin.ts +29 -0
  154. package/src/route-content-wrapper.tsx +96 -3
  155. package/src/route-definition/dsl-helpers.ts +28 -3
  156. package/src/route-definition/helpers-types.ts +13 -0
  157. package/src/route-definition/redirect.ts +17 -18
  158. package/src/router/error-handling.ts +65 -11
  159. package/src/router/intercept-resolution.ts +29 -0
  160. package/src/router/loader-resolution.ts +261 -28
  161. package/src/router/match-middleware/cache-lookup.ts +24 -15
  162. package/src/router/match-result.ts +7 -0
  163. package/src/router/revalidation.ts +24 -11
  164. package/src/router/route-trie-builder.ts +334 -0
  165. package/src/router/router-interfaces.ts +38 -0
  166. package/src/router/segment-resolution/fresh.ts +47 -0
  167. package/src/router/segment-resolution/helpers.ts +9 -11
  168. package/src/router/segment-resolution/loader-cache.ts +14 -24
  169. package/src/router/segment-resolution/revalidation.ts +20 -1
  170. package/src/router/trie-matching.ts +3 -3
  171. package/src/router.ts +46 -1
  172. package/src/rsc/full-payload.ts +6 -0
  173. package/src/rsc/handler.ts +36 -12
  174. package/src/rsc/helpers.ts +13 -0
  175. package/src/rsc/loader-fetch.ts +2 -2
  176. package/src/rsc/manifest-init.ts +28 -9
  177. package/src/rsc/progressive-enhancement.ts +247 -70
  178. package/src/rsc/render-pipeline.ts +68 -24
  179. package/src/rsc/routine-plan.ts +359 -0
  180. package/src/rsc/rsc-rendering.ts +569 -302
  181. package/src/rsc/server-action.ts +180 -71
  182. package/src/rsc/shell-capture-constants.ts +18 -0
  183. package/src/rsc/shell-capture.ts +104 -21
  184. package/src/rsc/shell-serve.ts +15 -2
  185. package/src/rsc/ssr-setup.ts +10 -1
  186. package/src/rsc/types.ts +31 -2
  187. package/src/segment-system.tsx +83 -26
  188. package/src/server/context.ts +10 -0
  189. package/src/server/cookie-store.ts +19 -19
  190. package/src/server/handle-store.ts +185 -48
  191. package/src/server/request-context.ts +36 -6
  192. package/src/server.ts +7 -0
  193. package/src/ssr/index.tsx +37 -2
  194. package/src/ssr/ssr-root.tsx +30 -2
  195. package/src/testing/dom.entry.ts +1 -1
  196. package/src/testing/render-route.tsx +22 -8
  197. package/src/testing/run-loader.ts +51 -13
  198. package/src/types/boundaries.ts +19 -0
  199. package/src/types/index.ts +1 -0
  200. package/src/types/loader-types.ts +60 -5
  201. package/src/types/segments.ts +7 -0
  202. package/src/urls/include-helper.ts +22 -4
  203. package/src/urls/path-helper-types.ts +14 -1
  204. package/src/use-loader.tsx +67 -6
  205. package/src/vite/discovery/client-urls-projection.ts +322 -0
  206. package/src/vite/discovery/discover-routers.ts +43 -17
  207. package/src/vite/discovery/state.ts +11 -1
  208. package/src/vite/discovery/virtual-module-codegen.ts +20 -0
  209. package/src/vite/encryption-key.ts +29 -0
  210. package/src/vite/plugins/expose-action-id.ts +2 -2
  211. package/src/vite/plugins/expose-internal-ids.ts +46 -0
  212. package/src/vite/plugins/server-ref-hashing.ts +74 -0
  213. package/src/vite/plugins/server-reference-pattern.ts +10 -0
  214. package/src/vite/plugins/virtual-entries.ts +12 -3
  215. package/src/vite/rango.ts +9 -0
  216. package/src/vite/router-discovery.ts +184 -14
  217. package/src/vite/utils/shared-utils.ts +12 -7
  218. package/dist/types.backup/__internal.d.ts +0 -127
  219. package/dist/types.backup/bin/rango.d.ts +0 -1
  220. package/dist/types.backup/browser/action-coordinator.d.ts +0 -57
  221. package/dist/types.backup/browser/action-fence.d.ts +0 -33
  222. package/dist/types.backup/browser/app-shell.d.ts +0 -34
  223. package/dist/types.backup/browser/app-version.d.ts +0 -6
  224. package/dist/types.backup/browser/connection-warmup.d.ts +0 -31
  225. package/dist/types.backup/browser/cookie-name.d.ts +0 -66
  226. package/dist/types.backup/browser/event-controller.d.ts +0 -221
  227. package/dist/types.backup/browser/history-state.d.ts +0 -26
  228. package/dist/types.backup/browser/index.d.ts +0 -1
  229. package/dist/types.backup/browser/intercept-utils.d.ts +0 -30
  230. package/dist/types.backup/browser/invalidate-client-cache.d.ts +0 -17
  231. package/dist/types.backup/browser/link-interceptor.d.ts +0 -43
  232. package/dist/types.backup/browser/logging.d.ts +0 -33
  233. package/dist/types.backup/browser/merge-segment-loaders.d.ts +0 -38
  234. package/dist/types.backup/browser/navigation-bridge.d.ts +0 -27
  235. package/dist/types.backup/browser/navigation-client.d.ts +0 -17
  236. package/dist/types.backup/browser/navigation-store-handle.d.ts +0 -25
  237. package/dist/types.backup/browser/navigation-store.d.ts +0 -95
  238. package/dist/types.backup/browser/navigation-transaction.d.ts +0 -75
  239. package/dist/types.backup/browser/network-error-handler.d.ts +0 -35
  240. package/dist/types.backup/browser/partial-update.d.ts +0 -61
  241. package/dist/types.backup/browser/prefetch/cache.d.ts +0 -183
  242. package/dist/types.backup/browser/prefetch/fetch.d.ts +0 -52
  243. package/dist/types.backup/browser/prefetch/observer.d.ts +0 -27
  244. package/dist/types.backup/browser/prefetch/policy.d.ts +0 -13
  245. package/dist/types.backup/browser/prefetch/queue.d.ts +0 -48
  246. package/dist/types.backup/browser/prefetch/resource-ready.d.ts +0 -28
  247. package/dist/types.backup/browser/rango-state.d.ts +0 -52
  248. package/dist/types.backup/browser/react/Link.d.ts +0 -140
  249. package/dist/types.backup/browser/react/NavigationProvider.d.ts +0 -88
  250. package/dist/types.backup/browser/react/ScrollRestoration.d.ts +0 -78
  251. package/dist/types.backup/browser/react/context.d.ts +0 -54
  252. package/dist/types.backup/browser/react/filter-segment-order.d.ts +0 -35
  253. package/dist/types.backup/browser/react/index.d.ts +0 -1
  254. package/dist/types.backup/browser/react/location-state-shared.d.ts +0 -162
  255. package/dist/types.backup/browser/react/location-state.d.ts +0 -29
  256. package/dist/types.backup/browser/react/mount-context.d.ts +0 -23
  257. package/dist/types.backup/browser/react/nonce-context.d.ts +0 -14
  258. package/dist/types.backup/browser/react/shallow-equal.d.ts +0 -5
  259. package/dist/types.backup/browser/react/use-action.d.ts +0 -61
  260. package/dist/types.backup/browser/react/use-handle.d.ts +0 -21
  261. package/dist/types.backup/browser/react/use-href.d.ts +0 -32
  262. package/dist/types.backup/browser/react/use-link-status.d.ts +0 -36
  263. package/dist/types.backup/browser/react/use-mount.d.ts +0 -24
  264. package/dist/types.backup/browser/react/use-navigation.d.ts +0 -15
  265. package/dist/types.backup/browser/react/use-params.d.ts +0 -21
  266. package/dist/types.backup/browser/react/use-pathname.d.ts +0 -13
  267. package/dist/types.backup/browser/react/use-reverse.d.ts +0 -40
  268. package/dist/types.backup/browser/react/use-router.d.ts +0 -23
  269. package/dist/types.backup/browser/react/use-search-params.d.ts +0 -19
  270. package/dist/types.backup/browser/react/use-segments.d.ts +0 -29
  271. package/dist/types.backup/browser/response-adapter.d.ts +0 -58
  272. package/dist/types.backup/browser/rsc-router.d.ts +0 -141
  273. package/dist/types.backup/browser/scroll-restoration.d.ts +0 -103
  274. package/dist/types.backup/browser/segment-reconciler.d.ts +0 -74
  275. package/dist/types.backup/browser/segment-structure-assert.d.ts +0 -16
  276. package/dist/types.backup/browser/server-action-bridge.d.ts +0 -29
  277. package/dist/types.backup/browser/types.d.ts +0 -530
  278. package/dist/types.backup/browser/validate-redirect-origin.d.ts +0 -28
  279. package/dist/types.backup/build/collect-fallback-refs.d.ts +0 -5
  280. package/dist/types.backup/build/generate-manifest.d.ts +0 -100
  281. package/dist/types.backup/build/generate-route-types.d.ts +0 -8
  282. package/dist/types.backup/build/index.d.ts +0 -21
  283. package/dist/types.backup/build/prefix-tree-utils.d.ts +0 -56
  284. package/dist/types.backup/build/route-types/ast-helpers.d.ts +0 -3
  285. package/dist/types.backup/build/route-types/ast-route-extraction.d.ts +0 -13
  286. package/dist/types.backup/build/route-types/codegen.d.ts +0 -16
  287. package/dist/types.backup/build/route-types/include-resolution.d.ts +0 -74
  288. package/dist/types.backup/build/route-types/param-extraction.d.ts +0 -13
  289. package/dist/types.backup/build/route-types/per-module-writer.d.ts +0 -18
  290. package/dist/types.backup/build/route-types/router-processing.d.ts +0 -82
  291. package/dist/types.backup/build/route-types/scan-filter.d.ts +0 -17
  292. package/dist/types.backup/build/route-types/source-scan.d.ts +0 -13
  293. package/dist/types.backup/build/runtime-discovery.d.ts +0 -24
  294. package/dist/types.backup/cache/background-task.d.ts +0 -21
  295. package/dist/types.backup/cache/cache-error.d.ts +0 -71
  296. package/dist/types.backup/cache/cache-key-utils.d.ts +0 -35
  297. package/dist/types.backup/cache/cache-policy.d.ts +0 -59
  298. package/dist/types.backup/cache/cache-runtime.d.ts +0 -51
  299. package/dist/types.backup/cache/cache-scope.d.ts +0 -134
  300. package/dist/types.backup/cache/cache-tag.d.ts +0 -79
  301. package/dist/types.backup/cache/cf/cf-base64.d.ts +0 -4
  302. package/dist/types.backup/cache/cf/cf-cache-constants.d.ts +0 -105
  303. package/dist/types.backup/cache/cf/cf-cache-store.d.ts +0 -481
  304. package/dist/types.backup/cache/cf/cf-cache-types.d.ts +0 -300
  305. package/dist/types.backup/cache/cf/cf-kv-utils.d.ts +0 -22
  306. package/dist/types.backup/cache/cf/cf-tag-marker-memo.d.ts +0 -15
  307. package/dist/types.backup/cache/cf/index.d.ts +0 -3
  308. package/dist/types.backup/cache/document-cache.d.ts +0 -69
  309. package/dist/types.backup/cache/handle-capture.d.ts +0 -23
  310. package/dist/types.backup/cache/handle-snapshot.d.ts +0 -39
  311. package/dist/types.backup/cache/index.d.ts +0 -7
  312. package/dist/types.backup/cache/memory-segment-store.d.ts +0 -163
  313. package/dist/types.backup/cache/profile-registry.d.ts +0 -40
  314. package/dist/types.backup/cache/read-through-swr.d.ts +0 -60
  315. package/dist/types.backup/cache/segment-codec.d.ts +0 -78
  316. package/dist/types.backup/cache/shell-snapshot.d.ts +0 -162
  317. package/dist/types.backup/cache/tag-invalidation.d.ts +0 -74
  318. package/dist/types.backup/cache/taint.d.ts +0 -71
  319. package/dist/types.backup/cache/types.d.ts +0 -407
  320. package/dist/types.backup/cache/vercel/index.d.ts +0 -1
  321. package/dist/types.backup/cache/vercel/vercel-cache-store.d.ts +0 -267
  322. package/dist/types.backup/client.d.ts +0 -184
  323. package/dist/types.backup/client.rsc.d.ts +0 -39
  324. package/dist/types.backup/cloudflare/index.d.ts +0 -7
  325. package/dist/types.backup/cloudflare/tracing.d.ts +0 -53
  326. package/dist/types.backup/component-utils.d.ts +0 -46
  327. package/dist/types.backup/components/DefaultDocument.d.ts +0 -13
  328. package/dist/types.backup/context-var.d.ts +0 -84
  329. package/dist/types.backup/debug.d.ts +0 -57
  330. package/dist/types.backup/decode-loader-results.d.ts +0 -5
  331. package/dist/types.backup/default-error-boundary.d.ts +0 -10
  332. package/dist/types.backup/defer.d.ts +0 -89
  333. package/dist/types.backup/deps/browser.d.ts +0 -1
  334. package/dist/types.backup/deps/html-stream-client.d.ts +0 -1
  335. package/dist/types.backup/deps/html-stream-server.d.ts +0 -1
  336. package/dist/types.backup/deps/rsc.d.ts +0 -1
  337. package/dist/types.backup/deps/ssr.d.ts +0 -1
  338. package/dist/types.backup/encode-kv.d.ts +0 -35
  339. package/dist/types.backup/errors.d.ts +0 -226
  340. package/dist/types.backup/escape-script.d.ts +0 -44
  341. package/dist/types.backup/handle.d.ts +0 -93
  342. package/dist/types.backup/handles/MetaTags.d.ts +0 -17
  343. package/dist/types.backup/handles/Scripts.d.ts +0 -38
  344. package/dist/types.backup/handles/breadcrumbs.d.ts +0 -43
  345. package/dist/types.backup/handles/deferred-resolution.d.ts +0 -53
  346. package/dist/types.backup/handles/is-thenable.d.ts +0 -12
  347. package/dist/types.backup/handles/meta.d.ts +0 -43
  348. package/dist/types.backup/handles/script.d.ts +0 -139
  349. package/dist/types.backup/host/cookie-handler.d.ts +0 -8
  350. package/dist/types.backup/host/errors.d.ts +0 -40
  351. package/dist/types.backup/host/index.d.ts +0 -33
  352. package/dist/types.backup/host/pattern-matcher.d.ts +0 -30
  353. package/dist/types.backup/host/router.d.ts +0 -12
  354. package/dist/types.backup/host/testing.d.ts +0 -41
  355. package/dist/types.backup/host/types.d.ts +0 -148
  356. package/dist/types.backup/host/utils.d.ts +0 -20
  357. package/dist/types.backup/href-client.d.ts +0 -214
  358. package/dist/types.backup/index.d.ts +0 -112
  359. package/dist/types.backup/index.rsc.d.ts +0 -51
  360. package/dist/types.backup/internal-debug.d.ts +0 -1
  361. package/dist/types.backup/loader-store.d.ts +0 -193
  362. package/dist/types.backup/loader.d.ts +0 -18
  363. package/dist/types.backup/loader.rsc.d.ts +0 -18
  364. package/dist/types.backup/missing-id-error.d.ts +0 -1
  365. package/dist/types.backup/outlet-context.d.ts +0 -12
  366. package/dist/types.backup/outlet-provider.d.ts +0 -12
  367. package/dist/types.backup/prerender/build-shell-capture.d.ts +0 -104
  368. package/dist/types.backup/prerender/param-hash.d.ts +0 -6
  369. package/dist/types.backup/prerender/shell-manifest-key.d.ts +0 -18
  370. package/dist/types.backup/prerender/store.d.ts +0 -62
  371. package/dist/types.backup/prerender.d.ts +0 -292
  372. package/dist/types.backup/redirect-origin.d.ts +0 -55
  373. package/dist/types.backup/regex-escape.d.ts +0 -6
  374. package/dist/types.backup/render-error-thrower.d.ts +0 -13
  375. package/dist/types.backup/response-utils.d.ts +0 -35
  376. package/dist/types.backup/reverse.d.ts +0 -206
  377. package/dist/types.backup/root-error-boundary.d.ts +0 -32
  378. package/dist/types.backup/route-content-wrapper.d.ts +0 -40
  379. package/dist/types.backup/route-definition/dsl-helpers.d.ts +0 -130
  380. package/dist/types.backup/route-definition/helper-factories.d.ts +0 -22
  381. package/dist/types.backup/route-definition/helpers-types.d.ts +0 -392
  382. package/dist/types.backup/route-definition/index.d.ts +0 -7
  383. package/dist/types.backup/route-definition/redirect.d.ts +0 -48
  384. package/dist/types.backup/route-definition/resolve-handler-use.d.ts +0 -19
  385. package/dist/types.backup/route-definition/use-item-types.d.ts +0 -1
  386. package/dist/types.backup/route-definition.d.ts +0 -1
  387. package/dist/types.backup/route-map-builder.d.ts +0 -127
  388. package/dist/types.backup/route-name.d.ts +0 -27
  389. package/dist/types.backup/route-types.d.ts +0 -172
  390. package/dist/types.backup/router/basename.d.ts +0 -10
  391. package/dist/types.backup/router/content-negotiation.d.ts +0 -91
  392. package/dist/types.backup/router/debug-manifest.d.ts +0 -7
  393. package/dist/types.backup/router/error-handling.d.ts +0 -76
  394. package/dist/types.backup/router/find-match.d.ts +0 -19
  395. package/dist/types.backup/router/handler-context.d.ts +0 -41
  396. package/dist/types.backup/router/instrument.d.ts +0 -161
  397. package/dist/types.backup/router/intercept-resolution.d.ts +0 -79
  398. package/dist/types.backup/router/lazy-includes.d.ts +0 -26
  399. package/dist/types.backup/router/loader-resolution.d.ts +0 -63
  400. package/dist/types.backup/router/logging.d.ts +0 -41
  401. package/dist/types.backup/router/manifest.d.ts +0 -8
  402. package/dist/types.backup/router/match-api.d.ts +0 -19
  403. package/dist/types.backup/router/match-context.d.ts +0 -184
  404. package/dist/types.backup/router/match-handlers.d.ts +0 -49
  405. package/dist/types.backup/router/match-middleware/background-revalidation.d.ts +0 -113
  406. package/dist/types.backup/router/match-middleware/cache-lookup.d.ts +0 -113
  407. package/dist/types.backup/router/match-middleware/cache-store.d.ts +0 -112
  408. package/dist/types.backup/router/match-middleware/index.d.ts +0 -80
  409. package/dist/types.backup/router/match-middleware/intercept-resolution.d.ts +0 -116
  410. package/dist/types.backup/router/match-middleware/segment-resolution.d.ts +0 -94
  411. package/dist/types.backup/router/match-pipelines.d.ts +0 -103
  412. package/dist/types.backup/router/match-result.d.ts +0 -114
  413. package/dist/types.backup/router/metrics.d.ts +0 -6
  414. package/dist/types.backup/router/middleware-types.d.ts +0 -74
  415. package/dist/types.backup/router/middleware.d.ts +0 -116
  416. package/dist/types.backup/router/navigation-snapshot.d.ts +0 -22
  417. package/dist/types.backup/router/params-util.d.ts +0 -8
  418. package/dist/types.backup/router/parse-pattern.d.ts +0 -38
  419. package/dist/types.backup/router/pattern-matching.d.ts +0 -169
  420. package/dist/types.backup/router/prefetch-cache-ttl.d.ts +0 -27
  421. package/dist/types.backup/router/prefetch-limits.d.ts +0 -20
  422. package/dist/types.backup/router/prerender-match.d.ts +0 -50
  423. package/dist/types.backup/router/preview-match.d.ts +0 -22
  424. package/dist/types.backup/router/request-classification.d.ts +0 -104
  425. package/dist/types.backup/router/revalidation.d.ts +0 -57
  426. package/dist/types.backup/router/route-snapshot.d.ts +0 -112
  427. package/dist/types.backup/router/router-context.d.ts +0 -137
  428. package/dist/types.backup/router/router-interfaces.d.ts +0 -432
  429. package/dist/types.backup/router/router-options.d.ts +0 -738
  430. package/dist/types.backup/router/router-registry.d.ts +0 -15
  431. package/dist/types.backup/router/segment-resolution/fresh.d.ts +0 -55
  432. package/dist/types.backup/router/segment-resolution/helpers.d.ts +0 -93
  433. package/dist/types.backup/router/segment-resolution/loader-cache.d.ts +0 -33
  434. package/dist/types.backup/router/segment-resolution/loader-mask.d.ts +0 -44
  435. package/dist/types.backup/router/segment-resolution/loader-snapshot.d.ts +0 -90
  436. package/dist/types.backup/router/segment-resolution/mask-nested.d.ts +0 -53
  437. package/dist/types.backup/router/segment-resolution/revalidation.d.ts +0 -85
  438. package/dist/types.backup/router/segment-resolution/static-store.d.ts +0 -17
  439. package/dist/types.backup/router/segment-resolution/streamed-handler-telemetry.d.ts +0 -16
  440. package/dist/types.backup/router/segment-resolution/view-transition-default.d.ts +0 -28
  441. package/dist/types.backup/router/segment-resolution.d.ts +0 -3
  442. package/dist/types.backup/router/segment-wrappers.d.ts +0 -53
  443. package/dist/types.backup/router/state-cookie-name.d.ts +0 -1
  444. package/dist/types.backup/router/substitute-pattern-params.d.ts +0 -23
  445. package/dist/types.backup/router/telemetry-otel.d.ts +0 -113
  446. package/dist/types.backup/router/telemetry.d.ts +0 -215
  447. package/dist/types.backup/router/timeout.d.ts +0 -68
  448. package/dist/types.backup/router/tracing.d.ts +0 -125
  449. package/dist/types.backup/router/trie-matching.d.ts +0 -32
  450. package/dist/types.backup/router/types.d.ts +0 -98
  451. package/dist/types.backup/router/url-params.d.ts +0 -26
  452. package/dist/types.backup/router.d.ts +0 -7
  453. package/dist/types.backup/rsc/capture-queue.d.ts +0 -6
  454. package/dist/types.backup/rsc/full-payload.d.ts +0 -22
  455. package/dist/types.backup/rsc/handler-context.d.ts +0 -31
  456. package/dist/types.backup/rsc/handler.d.ts +0 -9
  457. package/dist/types.backup/rsc/helpers.d.ts +0 -213
  458. package/dist/types.backup/rsc/index.d.ts +0 -17
  459. package/dist/types.backup/rsc/json-route-result.d.ts +0 -20
  460. package/dist/types.backup/rsc/loader-fetch.d.ts +0 -14
  461. package/dist/types.backup/rsc/manifest-init.d.ts +0 -18
  462. package/dist/types.backup/rsc/nonce.d.ts +0 -28
  463. package/dist/types.backup/rsc/origin-guard.d.ts +0 -50
  464. package/dist/types.backup/rsc/progressive-enhancement.d.ts +0 -19
  465. package/dist/types.backup/rsc/redirect-guard.d.ts +0 -35
  466. package/dist/types.backup/rsc/response-cache-serve.d.ts +0 -46
  467. package/dist/types.backup/rsc/response-error.d.ts +0 -19
  468. package/dist/types.backup/rsc/response-route-handler.d.ts +0 -29
  469. package/dist/types.backup/rsc/rsc-rendering.d.ts +0 -23
  470. package/dist/types.backup/rsc/runtime-warnings.d.ts +0 -22
  471. package/dist/types.backup/rsc/server-action.d.ts +0 -68
  472. package/dist/types.backup/rsc/shell-build-manifest.d.ts +0 -84
  473. package/dist/types.backup/rsc/shell-capture-constants.d.ts +0 -27
  474. package/dist/types.backup/rsc/shell-capture.d.ts +0 -374
  475. package/dist/types.backup/rsc/shell-serve.d.ts +0 -136
  476. package/dist/types.backup/rsc/ssr-setup.d.ts +0 -48
  477. package/dist/types.backup/rsc/transition-gate.d.ts +0 -27
  478. package/dist/types.backup/rsc/types.d.ts +0 -290
  479. package/dist/types.backup/runtime-env.d.ts +0 -1
  480. package/dist/types.backup/search-params.d.ts +0 -125
  481. package/dist/types.backup/segment-content-promise.d.ts +0 -13
  482. package/dist/types.backup/segment-fragments.d.ts +0 -56
  483. package/dist/types.backup/segment-loader-promise.d.ts +0 -22
  484. package/dist/types.backup/segment-system.d.ts +0 -84
  485. package/dist/types.backup/serialize.d.ts +0 -164
  486. package/dist/types.backup/server/context.d.ts +0 -494
  487. package/dist/types.backup/server/cookie-parse.d.ts +0 -10
  488. package/dist/types.backup/server/cookie-store.d.ts +0 -107
  489. package/dist/types.backup/server/fetchable-loader-store.d.ts +0 -20
  490. package/dist/types.backup/server/handle-store.d.ts +0 -100
  491. package/dist/types.backup/server/loader-registry.d.ts +0 -32
  492. package/dist/types.backup/server/request-context.d.ts +0 -596
  493. package/dist/types.backup/server/root-layout.d.ts +0 -3
  494. package/dist/types.backup/server.d.ts +0 -15
  495. package/dist/types.backup/ssr/index.d.ts +0 -233
  496. package/dist/types.backup/ssr/inject-rsc-eager.d.ts +0 -3
  497. package/dist/types.backup/ssr/preinit-client-references.d.ts +0 -71
  498. package/dist/types.backup/ssr/ssr-root.d.ts +0 -69
  499. package/dist/types.backup/static-handler.d.ts +0 -57
  500. package/dist/types.backup/testing/cache-status.d.ts +0 -63
  501. package/dist/types.backup/testing/collect-handle.d.ts +0 -20
  502. package/dist/types.backup/testing/dispatch.d.ts +0 -123
  503. package/dist/types.backup/testing/dom.entry.d.ts +0 -15
  504. package/dist/types.backup/testing/e2e/fixture.d.ts +0 -37
  505. package/dist/types.backup/testing/e2e/index.d.ts +0 -30
  506. package/dist/types.backup/testing/e2e/matchers.d.ts +0 -17
  507. package/dist/types.backup/testing/e2e/page-helpers.d.ts +0 -62
  508. package/dist/types.backup/testing/e2e/parity.d.ts +0 -111
  509. package/dist/types.backup/testing/e2e/server.d.ts +0 -35
  510. package/dist/types.backup/testing/flight-matchers.d.ts +0 -55
  511. package/dist/types.backup/testing/flight-normalize.d.ts +0 -1
  512. package/dist/types.backup/testing/flight-tree.d.ts +0 -192
  513. package/dist/types.backup/testing/flight.d.ts +0 -115
  514. package/dist/types.backup/testing/flight.entry.d.ts +0 -27
  515. package/dist/types.backup/testing/generated-routes.d.ts +0 -66
  516. package/dist/types.backup/testing/index.d.ts +0 -52
  517. package/dist/types.backup/testing/internal/context.d.ts +0 -225
  518. package/dist/types.backup/testing/internal/flight-client-globals.d.ts +0 -1
  519. package/dist/types.backup/testing/internal/seed-vars.d.ts +0 -30
  520. package/dist/types.backup/testing/render-handler.d.ts +0 -160
  521. package/dist/types.backup/testing/render-route.d.ts +0 -246
  522. package/dist/types.backup/testing/run-loader.d.ts +0 -186
  523. package/dist/types.backup/testing/run-middleware.d.ts +0 -132
  524. package/dist/types.backup/testing/run-transition-when.d.ts +0 -77
  525. package/dist/types.backup/testing/vitest-stubs/cloudflare-email.d.ts +0 -6
  526. package/dist/types.backup/testing/vitest-stubs/cloudflare-workers.d.ts +0 -13
  527. package/dist/types.backup/testing/vitest-stubs/plugin-rsc.d.ts +0 -7
  528. package/dist/types.backup/testing/vitest-stubs/version.d.ts +0 -1
  529. package/dist/types.backup/testing/vitest.d.ts +0 -205
  530. package/dist/types.backup/theme/ThemeProvider.d.ts +0 -13
  531. package/dist/types.backup/theme/ThemeScript.d.ts +0 -45
  532. package/dist/types.backup/theme/constants.d.ts +0 -39
  533. package/dist/types.backup/theme/index.d.ts +0 -29
  534. package/dist/types.backup/theme/theme-context.d.ts +0 -21
  535. package/dist/types.backup/theme/theme-script.d.ts +0 -26
  536. package/dist/types.backup/theme/types.d.ts +0 -162
  537. package/dist/types.backup/theme/use-theme.d.ts +0 -8
  538. package/dist/types.backup/types/boundaries.d.ts +0 -93
  539. package/dist/types.backup/types/cache-types.d.ts +0 -191
  540. package/dist/types.backup/types/error-types.d.ts +0 -114
  541. package/dist/types.backup/types/global-namespace.d.ts +0 -90
  542. package/dist/types.backup/types/handler-context.d.ts +0 -658
  543. package/dist/types.backup/types/index.d.ts +0 -11
  544. package/dist/types.backup/types/loader-types.d.ts +0 -182
  545. package/dist/types.backup/types/request-scope.d.ts +0 -93
  546. package/dist/types.backup/types/route-config.d.ts +0 -105
  547. package/dist/types.backup/types/route-entry.d.ts +0 -95
  548. package/dist/types.backup/types/segments.d.ts +0 -234
  549. package/dist/types.backup/types.d.ts +0 -1
  550. package/dist/types.backup/urls/include-helper.d.ts +0 -17
  551. package/dist/types.backup/urls/include-provider.d.ts +0 -27
  552. package/dist/types.backup/urls/index.d.ts +0 -6
  553. package/dist/types.backup/urls/path-helper-types.d.ts +0 -197
  554. package/dist/types.backup/urls/path-helper.d.ts +0 -12
  555. package/dist/types.backup/urls/pattern-types.d.ts +0 -166
  556. package/dist/types.backup/urls/response-types.d.ts +0 -67
  557. package/dist/types.backup/urls/type-extraction.d.ts +0 -157
  558. package/dist/types.backup/urls/urls-function.d.ts +0 -24
  559. package/dist/types.backup/urls.d.ts +0 -1
  560. package/dist/types.backup/use-loader.d.ts +0 -150
  561. package/dist/types.backup/vercel/index.d.ts +0 -10
  562. package/dist/types.backup/vercel/tracing.d.ts +0 -70
  563. package/dist/types.backup/vite/debug.d.ts +0 -80
  564. package/dist/types.backup/vite/discovery/bundle-postprocess.d.ts +0 -12
  565. package/dist/types.backup/vite/discovery/dev-prerender-cache.d.ts +0 -65
  566. package/dist/types.backup/vite/discovery/discover-routers.d.ts +0 -17
  567. package/dist/types.backup/vite/discovery/discovery-errors.d.ts +0 -113
  568. package/dist/types.backup/vite/discovery/gate-state.d.ts +0 -79
  569. package/dist/types.backup/vite/discovery/prerender-collection.d.ts +0 -24
  570. package/dist/types.backup/vite/discovery/route-types-writer.d.ts +0 -32
  571. package/dist/types.backup/vite/discovery/self-gen-tracking.d.ts +0 -22
  572. package/dist/types.backup/vite/discovery/shell-prerender-phase.d.ts +0 -40
  573. package/dist/types.backup/vite/discovery/state.d.ts +0 -162
  574. package/dist/types.backup/vite/discovery/virtual-module-codegen.d.ts +0 -15
  575. package/dist/types.backup/vite/index.d.ts +0 -11
  576. package/dist/types.backup/vite/inject-client-debug.d.ts +0 -56
  577. package/dist/types.backup/vite/plugin-types.d.ts +0 -298
  578. package/dist/types.backup/vite/plugins/cjs-to-esm.d.ts +0 -6
  579. package/dist/types.backup/vite/plugins/client-ref-dedup.d.ts +0 -40
  580. package/dist/types.backup/vite/plugins/client-ref-hashing.d.ts +0 -35
  581. package/dist/types.backup/vite/plugins/cloudflare-protocol-stub.d.ts +0 -64
  582. package/dist/types.backup/vite/plugins/expose-action-id.d.ts +0 -18
  583. package/dist/types.backup/vite/plugins/expose-id-utils.d.ts +0 -37
  584. package/dist/types.backup/vite/plugins/expose-ids/export-analysis.d.ts +0 -19
  585. package/dist/types.backup/vite/plugins/expose-ids/handler-transform.d.ts +0 -10
  586. package/dist/types.backup/vite/plugins/expose-ids/loader-transform.d.ts +0 -8
  587. package/dist/types.backup/vite/plugins/expose-ids/router-transform.d.ts +0 -13
  588. package/dist/types.backup/vite/plugins/expose-ids/types.d.ts +0 -29
  589. package/dist/types.backup/vite/plugins/expose-internal-ids.d.ts +0 -6
  590. package/dist/types.backup/vite/plugins/performance-tracks.d.ts +0 -25
  591. package/dist/types.backup/vite/plugins/refresh-cmd.d.ts +0 -20
  592. package/dist/types.backup/vite/plugins/use-cache-transform.d.ts +0 -20
  593. package/dist/types.backup/vite/plugins/vercel-output.d.ts +0 -85
  594. package/dist/types.backup/vite/plugins/version-injector.d.ts +0 -21
  595. package/dist/types.backup/vite/plugins/version-plugin.d.ts +0 -19
  596. package/dist/types.backup/vite/plugins/virtual-entries.d.ts +0 -36
  597. package/dist/types.backup/vite/plugins/virtual-stub-plugin.d.ts +0 -7
  598. package/dist/types.backup/vite/rango.d.ts +0 -29
  599. package/dist/types.backup/vite/router-discovery.d.ts +0 -23
  600. package/dist/types.backup/vite/utils/ast-handler-extract.d.ts +0 -64
  601. package/dist/types.backup/vite/utils/banner.d.ts +0 -2
  602. package/dist/types.backup/vite/utils/bundle-analysis.d.ts +0 -28
  603. package/dist/types.backup/vite/utils/client-chunks.d.ts +0 -55
  604. package/dist/types.backup/vite/utils/directive-prologue.d.ts +0 -16
  605. package/dist/types.backup/vite/utils/forward-user-plugins.d.ts +0 -37
  606. package/dist/types.backup/vite/utils/manifest-utils.d.ts +0 -7
  607. package/dist/types.backup/vite/utils/package-resolution.d.ts +0 -6
  608. package/dist/types.backup/vite/utils/prerender-utils.d.ts +0 -32
  609. package/dist/types.backup/vite/utils/shared-utils.d.ts +0 -55
@@ -51,26 +51,63 @@ Returns the pathname string without search params or hash. Updates on navigation
51
51
 
52
52
  ### useSearchParams()
53
53
 
54
- Access the current URL search params:
54
+ Read and write the current URL search params (React Router-style tuple):
55
55
 
56
56
  ```tsx
57
57
  "use client";
58
58
  import { useSearchParams } from "@rangojs/router/client";
59
59
 
60
60
  function SearchResults() {
61
- const searchParams = useSearchParams();
61
+ const [searchParams, setSearchParams] = useSearchParams();
62
62
  const query = searchParams.get("q"); // "react"
63
63
  const page = searchParams.get("page"); // "2"
64
64
 
65
65
  return (
66
66
  <div>
67
67
  Searching for: {query}, page {page}
68
+ <button onClick={() => setSearchParams({ q: query ?? "", page: "2" })}>
69
+ Page 2
70
+ </button>
68
71
  </div>
69
72
  );
70
73
  }
71
74
  ```
72
75
 
73
- Returns a `ReadonlyURLSearchParams` (URLSearchParams without mutation methods). During SSR, returns empty params and syncs from the browser URL on mount.
76
+ The first element is a `ReadonlyURLSearchParams` (URLSearchParams without
77
+ mutation methods) from the committed location. During document SSR it
78
+ carries the live request's search (seeded into the SSR store), and the
79
+ browser's first render seeds from its own URL — hydration agrees by
80
+ construction. On ppr routes search is part of shell identity: the shell key
81
+ embeds the sorted search and the capture/resume renders seed that same
82
+ string, so static-part reads are legal and per-shell-correct. Edges: params
83
+ excluded by `cache.searchParams` are absent in shell renders, and
84
+ `.toString()` renders sorted order.
85
+
86
+ The setter REPLACES the whole search string (React Router semantics) and
87
+ navigates to the current pathname with the new params — a same-route
88
+ navigation, so loaders re-evaluate per their `revalidate()` contract and the
89
+ commit holds previous content. Accepted inits: a string, a `URLSearchParams`,
90
+ a record (numbers/booleans stringified, arrays append, `null`/`undefined`
91
+ skipped), or a function receiving a mutable copy of the current params for
92
+ merging:
93
+
94
+ ```tsx
95
+ // Merge: keep everything, change one key
96
+ setSearchParams((prev) => {
97
+ prev.set("page", "3");
98
+ return prev;
99
+ });
100
+
101
+ // Filter UIs usually want replace + preserved scroll
102
+ setSearchParams({ category: "home" }, { replace: true, scroll: false });
103
+
104
+ // URL-only update: skip the server fetch for purely client-derived state
105
+ setSearchParams({ view: "grid" }, { revalidate: false });
106
+ ```
107
+
108
+ Options: `replace` (default false — push), `scroll` (default true),
109
+ `revalidate` (default true; `false` skips the server fetch — legal because
110
+ the setter never changes the pathname).
74
111
 
75
112
  ### useHref()
76
113
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: loader
3
- description: Define data loaders for fetching data in routes with createLoader. Use when pages need per-request data that stays fresh, data should stream while the page renders, or client components need reactive server data.
4
- argument-hint: [loader]
3
+ description: Define data loaders for fetching data in routes with createLoader. Use when pages need per-request data that stays fresh, data should stream while the page renders, client components need reactive server data, a loader should throw notFound()/redirect(), set page meta/breadcrumbs from loader data (handle writes), or loader data must be guaranteed in the SSR'd document (stream:"navigation").
4
+ argument-hint: "[loader]"
5
5
  ---
6
6
 
7
7
  # Data Loaders with loader()
@@ -172,23 +172,23 @@ Loaders receive the same context shape as route handlers.
172
172
 
173
173
  ### Full field surface
174
174
 
175
- | Field | Type | Notes |
176
- | -------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
177
- | `params` | `TParams` | Merged route + explicit loader params; overridable by fetchable `load({ params })`. |
178
- | `routeParams` | `Record<string, string>` | Server-trusted route params from URL pattern matching; cannot be overridden. |
179
- | `request` | `Request` | The incoming `Request` (headers, method, body, `signal` for abort). |
180
- | `url` | `URL` | Parsed request URL. |
181
- | `pathname` | `string` | URL pathname (shortcut for `ctx.url.pathname`). |
182
- | `searchParams` | `URLSearchParams` | Shortcut for `ctx.url.searchParams`. |
183
- | `search` | `ResolveSearchSchema<TSearch>` | Typed query params when a search schema is declared on the route; `{}` otherwise. |
184
- | `env` | `TEnv` | Plain bindings from `createRouter<TEnv>()` (DB, KV, secrets, etc.). |
185
- | `get` | `(key \| ContextVar) => value` | Reads variables/context-vars set by middleware. |
186
- | `use` | `(loader \| handle) => T` | Access another loader's data (Promise) or a handle's collected data (after `await ctx.rendered()`). |
187
- | `rendered` | `() => Promise<void>` | **Experimental.** DSL loaders only — waits for all non-loader segments (including `loading()` streaming handlers) to settle before reading handle data. |
188
- | `method` | `string` | HTTP method. `"GET"` for SSR loader runs; reflects real method for fetchable loaders. |
189
- | `body` | `TBody \| undefined` | Parsed request body for fetchable POST/PUT/PATCH/DELETE calls. |
190
- | `formData` | `FormData \| undefined` | Present when a fetchable loader is invoked via form submission. |
191
- | `reverse` | `ScopedReverseFunction` | Generate type-checked URLs from route names (same scoped semantics as route handlers). |
175
+ | Field | Type | Notes |
176
+ | -------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
177
+ | `params` | `TParams` | Merged route + explicit loader params; overridable by fetchable `load({ params })`. |
178
+ | `routeParams` | `Record<string, string>` | Server-trusted route params from URL pattern matching; cannot be overridden. |
179
+ | `request` | `Request` | The incoming `Request` (headers, method, body, `signal` for abort). |
180
+ | `url` | `URL` | Parsed request URL. |
181
+ | `pathname` | `string` | URL pathname (shortcut for `ctx.url.pathname`). |
182
+ | `searchParams` | `URLSearchParams` | Shortcut for `ctx.url.searchParams`. |
183
+ | `search` | `ResolveSearchSchema<TSearch>` | Typed query params when a search schema is declared on the route; `{}` otherwise. |
184
+ | `env` | `TEnv` | Plain bindings from `createRouter<TEnv>()` (DB, KV, secrets, etc.). |
185
+ | `get` | `(key \| ContextVar \| handle)` | Reads middleware variables/context-vars or READS a handle's collected data, after `await ctx.rendered()`. |
186
+ | `use` | `(loader \| handle) => T` | Access another loader's data (Promise), or WRITE a handle: `ctx.use(Meta)({ title })` returns the push function — handler parity. Reads moved to `get`. |
187
+ | `rendered` | `() => Promise<void>` | **Experimental.** DSL loaders only — waits for all non-loader segments (including `loading()` streaming handlers) to settle before reading handle data. Not with `stream: "navigation"` (cycle; throws). |
188
+ | `method` | `string` | HTTP method. `"GET"` for SSR loader runs; reflects real method for fetchable loaders. |
189
+ | `body` | `TBody \| undefined` | Parsed request body for fetchable POST/PUT/PATCH/DELETE calls. |
190
+ | `formData` | `FormData \| undefined` | Present when a fetchable loader is invoked via form submission. |
191
+ | `reverse` | `ScopedReverseFunction` | Generate type-checked URLs from route names (same scoped semantics as route handlers). |
192
192
 
193
193
  ### Example
194
194
 
@@ -442,7 +442,10 @@ boundary a parallel loader blocks its parent, so add one to keep the overlap.)
442
442
 
443
443
  If you come from a framework where the loader is a blocking step that runs
444
444
  before the response is built, this is the shift to internalize: here the
445
- response starts streaming first and loader data fills in.
445
+ response starts streaming first and loader data fills in. (The one deliberate
446
+ exception is per-loader: `loader(Def, { stream: "navigation" })` awaits that
447
+ loader before first flush on document renders — see "`stream: "navigation"`"
448
+ below.)
446
449
 
447
450
  ### See it: `debugPerformance`
448
451
 
@@ -660,6 +663,115 @@ function ProductPage() {
660
663
  }
661
664
  ```
662
665
 
666
+ ## Loader Authority: notFound() and redirect()
667
+
668
+ A loader may **throw** `notFound()` and `redirect()` — data-dependent
669
+ authority lives with the data, so every consumer of the loader inherits the
670
+ signal instead of re-checking existence at each read site:
671
+
672
+ ```typescript
673
+ import { createLoader, notFound, redirect } from "@rangojs/router";
674
+
675
+ export const ProductLoader = createLoader(async (ctx) => {
676
+ "use server";
677
+ const moved = LEGACY_SLUGS[ctx.params.slug];
678
+ if (moved) throw redirect(`/shop/product/${moved}`);
679
+
680
+ // Existence check BEFORE the expensive fetch: a near-instant rejection
681
+ // usually wins the race to first flush (see the semantics below).
682
+ if (!(await exists(ctx.params.slug))) notFound(`No "${ctx.params.slug}"`);
683
+
684
+ return getProduct(ctx.params.slug);
685
+ });
686
+ ```
687
+
688
+ Semantics by lane:
689
+
690
+ | Signal | Document load | Client navigation |
691
+ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
692
+ | `notFound()` | Not-found UI resolves server-side (nearest `notFoundBoundary` → router option → default) and rides the envelope; the 404 STATUS is **opportunistic** — real only if the rejection beats Response construction. `stream: "navigation"` (below) makes it deterministic. | 404 UI swaps in, URL preserved, payload stays 200 |
693
+ | `redirect()` | 200 document, then a client-side replace to the target — **no document-lane 302 from loaders**; pre-stream redirect authority belongs to middleware | Redirect envelope navigates to the target |
694
+
695
+ Session/auth gates belong in middleware (they are request-shaped, not
696
+ data-shaped, and middleware CAN emit a real pre-stream 302). Data-dependent
697
+ "this slug moved / does not exist" belongs in the loader.
698
+
699
+ ## Writing Handles from Loaders (meta, breadcrumbs)
700
+
701
+ Loader bodies can WRITE handles with handler parity — `ctx.use(Handle)`
702
+ returns the push function, legal for the whole body, streaming loaders
703
+ included. This is how data-derived page titles and breadcrumb trails live
704
+ where the data lives:
705
+
706
+ ```typescript
707
+ import { Meta, Breadcrumbs } from "./handles";
708
+
709
+ export const ProductLoader = createLoader(async (ctx) => {
710
+ "use server";
711
+ const product = await getProduct(ctx.params.slug);
712
+
713
+ ctx.use(Meta)({ title: `${product.name} — Shop` });
714
+ const pushCrumb = ctx.use(Breadcrumbs);
715
+ pushCrumb({ label: "Shop", href: "/shop" });
716
+ pushCrumb({ label: product.name, href: `/shop/product/${product.slug}` });
717
+
718
+ return product;
719
+ });
720
+ ```
721
+
722
+ Delivery is async **by the race model**: pushes that settle before the handler
723
+ barrier ride the SSR handle snapshot (in the SSR'd document — `<MetaTags />`,
724
+ `useHandle` reads); later pushes stream to the client and apply post-hydration
725
+ on document loads (`metadata.handlesLate`) or progressively on navigations.
726
+ A push before your slow fetch usually beats the barrier; a push derived from
727
+ the fetched data usually does not. When it MUST be in the document, use
728
+ `stream: "navigation"` below.
729
+
730
+ Reads are the other direction and gated: `ctx.get(handle)` throws unless the
731
+ loader first does `await ctx.rendered()` (DSL-registered loaders only —
732
+ handler-invoked loaders cannot use `rendered()`, and a handler already
733
+ awaiting the loader via `ctx.use()` makes it a detected deadlock).
734
+
735
+ ## `stream: "navigation"` — Guarantee a Loader in the Document
736
+
737
+ Streaming means nothing a slow loader produces is _guaranteed_ in the SSR'd
738
+ HTML: its section SSRs as the fallback, a late handle push applies
739
+ post-hydration, a late `notFound()` loses the status race. When the loader
740
+ feeds something that must exist in the document — `<head>` meta via a handle,
741
+ or a real 404 status — pass delivery options between the definition and the
742
+ use callback:
743
+
744
+ ```typescript
745
+ path("/product/:slug", ProductPage, { name: "product" }, () => [
746
+ loader(ProductLoader, { stream: "navigation" }, () => [cache({ ttl: 60 })]),
747
+ loader(RelatedLoader), // untouched: still streams behind its boundary
748
+ ]),
749
+ ```
750
+
751
+ The name says WHERE streaming still applies, not that it is disabled:
752
+ document renders await this loader before first flush — data is settled
753
+ (`useLoader` reads it synchronously, no fallback paints), handle pushes beat
754
+ the barrier snapshot, and a thrown `notFound()` deterministically precedes
755
+ Response construction (real 404, no warm-up race). Client navigations stream
756
+ exactly as before. Scoped per LOADER: the flagged loader awaits only itself;
757
+ siblings keep streaming.
758
+
759
+ The costs and constraints:
760
+
761
+ - Every document load pays the flagged loader's latency before first byte.
762
+ That is the point — but keep flagged loaders fast, and flag loaders, not
763
+ routes.
764
+ - A flagged loader must not `await ctx.rendered()` / `ctx.get(handle)` — the
765
+ document render awaits the loader before the render barrier resolves, so
766
+ that wait is a cycle by construction; it throws a deadlock error naming the
767
+ fix.
768
+ - PPR capture renders mask loaders and skip the await — the flag does not
769
+ bake anything into a shell (`/ppr`).
770
+
771
+ Also available in `clientUrls()` route groups (`/client-urls`), where the
772
+ loader-heavy shape makes it most useful. `LoaderOptions` is exported from the
773
+ package root.
774
+
663
775
  ## Fetchable Loaders
664
776
 
665
777
  By default, loaders only run during SSR and navigation. Pass `true` as the second
@@ -657,15 +657,45 @@ children in their scope — handlers, loaders, and nested segments.
657
657
 
658
658
  ## 6. Navigation
659
659
 
660
- | Next.js | Rango |
661
- | ------------------------------- | ------------------------------------------------- |
662
- | `import Link from "next/link"` | `import { Link } from "@rangojs/router/client"` |
663
- | `<Link href="/about">` | `<Link to="/about">` |
664
- | `useRouter().push("/about")` | `useRouter().push("/about")` |
665
- | `useRouter().replace("/about")` | `useRouter().replace("/about")` |
666
- | `usePathname()` | `usePathname()` from `@rangojs/router/client` |
667
- | `useSearchParams()` | `useSearchParams()` from `@rangojs/router/client` |
668
- | `redirect("/login")` (server) | `redirect("/login")` from `@rangojs/router` |
660
+ | Next.js | Rango |
661
+ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
662
+ | `import Link from "next/link"` | `import { Link } from "@rangojs/router/client"` |
663
+ | `<Link href="/about">` | `<Link to="/about">` |
664
+ | `useRouter().push("/about")` | `useRouter().push("/about")` |
665
+ | `useRouter().replace("/about")` | `useRouter().replace("/about")` |
666
+ | `usePathname()` | `usePathname()` from `@rangojs/router/client` |
667
+ | `useSearchParams()` | `useSearchParams()` from `@rangojs/router/client` — returns an RR-style TUPLE, so destructure the reader: `const [searchParams] = useSearchParams()`; the second element is a setter Next does not have |
668
+ | `redirect("/login")` (server) | `redirect("/login")` from `@rangojs/router` |
669
+
670
+ ### "Instant navigations" (Link prefetching)
671
+
672
+ Next.js's instant navigations — `<Link>` auto-prefetch feeding the client
673
+ router cache — map to Rango's prefetch system: per-Link
674
+ `prefetch="viewport" | "hover" | "none"` (or the router-wide `defaultPrefetch`
675
+ option) warms the target's partial RSC payload before the click, and a click
676
+ on a warmed link commits the prefetched payload as a whole — the complete
677
+ page lands instantly, no fetch waterfall. Prefetched entries survive being
678
+ used (they re-arm in place) and expire by `prefetchCacheTTL`; actions and
679
+ `invalidateClientCache()` flush them so a stale payload is never committed.
680
+
681
+ ```tsx
682
+ <Link to="/product/widget" prefetch="viewport">
683
+ Widget
684
+ </Link>
685
+ ```
686
+
687
+ Two differences from Next.js worth knowing: the trigger is an explicit choice
688
+ (viewport vs hover vs none) rather than an internal scheduler, and container
689
+ opt-outs exist for whole DOM sections (`data-prefetch-scope="none"`). See
690
+ `/links` → "Prefetch boundaries".
691
+
692
+ For **dashboard / admin / settings-shaped sections** — high navigation
693
+ frequency inside one layout, mostly tab/param/filter switches — also consider
694
+ porting that route group to `clientUrls()` (`/client-urls`): the definition
695
+ matches in the browser (instant optimistic pending, no server round-trip to
696
+ start a transition) and browser-run `revalidate()` predicates hold data across
697
+ switches that don't invalidate it, which is the fastest transition shape Rango
698
+ has. Server-component routes and `clientUrls()` groups compose in one tree.
669
699
 
670
700
  ## 7. Server Actions
671
701
 
@@ -694,6 +724,34 @@ const HomePage: Handler<"home"> = (ctx) => {
694
724
  };
695
725
  ```
696
726
 
727
+ `generateMetadata({ params })` — DATA-derived, document-blocking metadata —
728
+ maps to a Meta push from the LOADER that owns the data, plus
729
+ `{ stream: "navigation" }` for the blocking-until-in-head part:
730
+
731
+ ```typescript
732
+ // Next.js: export async function generateMetadata({ params }) {
733
+ // const product = await getProduct(params.slug);
734
+ // return { title: product.name };
735
+ // }
736
+
737
+ // Rango: push from the loader; the flag makes the document render await it,
738
+ // so the title is in the SSR'd <head> like generateMetadata guarantees.
739
+ export const ProductLoader = createLoader(async (ctx) => {
740
+ "use server";
741
+ const product = await getProduct(ctx.params.slug);
742
+ ctx.use(Meta)({ title: product.name });
743
+ return product;
744
+ });
745
+
746
+ path("/product/:slug", ProductPage, { name: "product" }, () => [
747
+ loader(ProductLoader, { stream: "navigation" }),
748
+ ]);
749
+ ```
750
+
751
+ Without the flag the push still applies, but a slow loader's title lands
752
+ post-hydration instead of in the document — see `/loader` → "Writing Handles
753
+ from Loaders" for the delivery race.
754
+
697
755
  Add `<MetaTags />` in the Document component's `<head>`:
698
756
 
699
757
  ```typescript
@@ -780,10 +838,12 @@ See `/theme` for full API including system detection and cookie persistence.
780
838
  6. [ ] Migrate layouts to `layout()` with `<Outlet />`
781
839
  7. [ ] Convert data fetching to `createLoader()` + `ctx.use()`
782
840
  8. [ ] Migrate `middleware.ts` to `router.use()` (auth, guards, logging)
783
- 9. [ ] Replace `next/link` with `Link` from `@rangojs/router/client`
841
+ 9. [ ] Replace `next/link` with `Link` from `@rangojs/router/client`; keep
842
+ "instant navigations" via `prefetch="viewport"`/`defaultPrefetch` (§6)
784
843
  10. [ ] Convert loading/error files to `loading()` / `errorBoundary()`
785
844
  11. [ ] Migrate API routes to `path.json()` / `path.text()`
786
845
  12. [ ] Update metadata to use `Meta` handle + `<MetaTags />` in document head
846
+ (`generateMetadata` → loader push + `{ stream: "navigation" }`)
787
847
  13. [ ] Replace `next-themes` with `theme: true` in createRouter (see `/theme`)
788
848
  14. [ ] Map rendering-mode segment config: `revalidate = N` → `cache({ ttl })`,
789
849
  `force-static` → `Static()`/`Prerender()`, `experimental_ppr` → the
@@ -59,6 +59,42 @@ React Router v7 has two modes that require different migration paths:
59
59
  React Router v6 and Remix v2 follow the same patterns as v7 library mode and
60
60
  framework mode respectively.
61
61
 
62
+ ## Two target shapes: server handlers or clientUrls()
63
+
64
+ Every RR route lands in one of two Rango shapes — pick per route group, not
65
+ per app (both compose in one `urls()` tree via `include()`):
66
+
67
+ - **Server handlers** (the default in this guide): the route component becomes
68
+ a server component, data fetching merges into the handler. This is the shape
69
+ with the biggest wins — server-first rendering, smaller client bundles — and
70
+ the right target whenever the component CAN become a server component.
71
+
72
+ - **`clientUrls()` groups** (`/client-urls`): for route groups whose components
73
+ are irreducibly hook-heavy client components, this is the mechanical port —
74
+ the RR route-module shape maps almost 1:1 and nothing changes seat:
75
+
76
+ | RR route module | clientUrls() |
77
+ | -------------------------------- | -------------------------------------------------------- |
78
+ | component (client, hooks) | stays a client component — no conversion |
79
+ | `loader` (throws `redirect`/404) | `createLoader()` — thrown `redirect()`/`notFound()` kept |
80
+ | `useLoaderData()` | `useLoader(Loader)` at the read site, under `<Suspense>` |
81
+ | `shouldRevalidate` (runs client) | `revalidate()` predicate — ALSO runs in the browser |
82
+ | `meta({ data })` | `ctx.use(Meta)` push from the loader body |
83
+ | `defer` / `Await` | loaders stream; `<Suspense>` above each read |
84
+
85
+ Note the `shouldRevalidate` row: a server-tree `revalidate()` runs on the
86
+ server, but a `clientUrls()` predicate runs in the browser with
87
+ client-computable args — the exact RR semantics. A group ported this way can
88
+ still be re-migrated to server handlers later, route by route.
89
+
90
+ Start with server handlers; reach for `clientUrls()` when a route group's
91
+ conversion cost is dominated by rewriting interactive components rather than
92
+ by moving data fetching — or when the group is a **high-navigation-speed
93
+ surface** (dashboard, admin panel, settings): browser-local matching gives
94
+ instant optimistic pending, and browser-run predicates hold data across
95
+ tab/param switches, so transitions are the fastest Rango offers. See
96
+ `/client-urls`.
97
+
62
98
  ## Migration Strategy
63
99
 
64
100
  Work route-by-route, bottom-up. Start with leaf routes, then layouts, then
@@ -73,19 +109,19 @@ unsupported behavior until runtime, and keep the old packages in the dependency
73
109
  graph. Replace every `react-router` / `react-router-dom` / `@remix-run/*`
74
110
  import at its call site:
75
111
 
76
- | React Router import | Replace with |
77
- | --------------------------------------------- | ----------------------------------------------------------------------------------------- |
78
- | `Link`, `NavLink` | `Link` from `@rangojs/router/client` (`NavLink` active state via `usePathname()`, see §6) |
79
- | `Outlet` | `Outlet` from `@rangojs/router/client` |
80
- | `useNavigate` | `useRouter()` from `@rangojs/router/client` (see §6) |
81
- | `useLocation`, `useSearchParams`, `useParams` | `usePathname()`, `useSearchParams()`, `useParams()` from `@rangojs/router/client` |
82
- | `useLoaderData` | merge the loader into the handler; `useLoader()` only for live client data (see §3) |
83
- | `useActionData` | `useActionState` (standard React, see §3) |
84
- | `Form` | `<form action={serverAction}>` with a `"use server"` function (see §3) |
85
- | `useFetcher` | submits → server actions + `useActionState`/`useOptimistic`; reads → `useLoader()` |
86
- | `defer` / `Await` | `loading()` DSL / plain `<Suspense>` (see §5) |
87
- | `json()`, `redirect()` | plain return values; `redirect` from `@rangojs/router` |
88
- | `useRouteError` | the `error` prop of `errorBoundary()` (see §5) |
112
+ | React Router import | Replace with |
113
+ | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
114
+ | `Link`, `NavLink` | `Link` from `@rangojs/router/client` (`NavLink` active state via `usePathname()`, see §6) |
115
+ | `Outlet` | `Outlet` from `@rangojs/router/client` |
116
+ | `useNavigate` | `useRouter()` from `@rangojs/router/client` (see §6) |
117
+ | `useLocation`, `useSearchParams`, `useParams` | `usePathname()`, `useSearchParams()` (same `[params, setParams]` tuple), `useParams()` from `@rangojs/router/client` |
118
+ | `useLoaderData` | merge the loader into the handler; `useLoader()` for live client data or `clientUrls()` routes (see §3) |
119
+ | `useActionData` | `useActionState` (standard React, see §3) |
120
+ | `Form` | `<form action={serverAction}>` with a `"use server"` function (see §3) |
121
+ | `useFetcher` | submits → server actions + `useActionState`/`useOptimistic`; reads → `useLoader()` |
122
+ | `defer` / `Await` | `loading()` DSL / plain `<Suspense>` (see §5) |
123
+ | `json()`, `redirect()` | plain return values; `redirect` from `@rangojs/router` |
124
+ | `useRouteError` | the `error` prop of `errorBoundary()` (see §5) |
89
125
 
90
126
  If an import has no row here and no obvious Rango equivalent, stop and surface
91
127
  it to the user — do not mock it to keep the build green.
@@ -85,19 +85,19 @@ layout(<ShopLayout />, () => [
85
85
 
86
86
  ## 6. Navigation
87
87
 
88
- | React Router | Rango |
89
- | ----------------------------------------- | -------------------------------------------------------------------------------- |
90
- | `import { Link } from "react-router-dom"` | `import { Link } from "@rangojs/router/client"` |
91
- | `<Link to="/about">` | `<Link to="/about">` |
92
- | `useNavigate()` | `useRouter()` from `@rangojs/router/client` |
93
- | `navigate("/about")` | `useRouter().push("/about")` |
94
- | `navigate("/about", { replace: true })` | `useRouter().replace("/about")` |
95
- | `navigate(-1)` | `useRouter().back()` |
96
- | `useLocation().pathname` | `usePathname()` from `@rangojs/router/client` |
97
- | `useSearchParams()` | `useSearchParams()` from `@rangojs/router/client` |
98
- | `useParams()` | `useParams()` from `@rangojs/router/client` (or `ctx.params` in server handlers) |
99
- | `useParams<T>()` | `useParams<T>()` — same generic annotation pattern |
100
- | `<NavLink>` | `<Link>` with `usePathname()` for active state |
88
+ | React Router | Rango |
89
+ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
90
+ | `import { Link } from "react-router-dom"` | `import { Link } from "@rangojs/router/client"` |
91
+ | `<Link to="/about">` | `<Link to="/about">` |
92
+ | `useNavigate()` | `useRouter()` from `@rangojs/router/client` |
93
+ | `navigate("/about")` | `useRouter().push("/about")` |
94
+ | `navigate("/about", { replace: true })` | `useRouter().replace("/about")` |
95
+ | `navigate(-1)` | `useRouter().back()` |
96
+ | `useLocation().pathname` | `usePathname()` from `@rangojs/router/client` |
97
+ | `useSearchParams()` | `useSearchParams()` from `@rangojs/router/client` — same `[params, setParams]` tuple; setter replaces the whole search string, options `{ replace, scroll, revalidate }` |
98
+ | `useParams()` | `useParams()` from `@rangojs/router/client` (or `ctx.params` in server handlers) |
99
+ | `useParams<T>()` | `useParams<T>()` — same generic annotation pattern |
100
+ | `<NavLink>` | `<Link>` with `usePathname()` for active state |
101
101
 
102
102
  ### useNavigate → useRouter
103
103
 
@@ -132,6 +132,11 @@ const HomePage: Handler<"home"> = (ctx) => {
132
132
  };
133
133
  ```
134
134
 
135
+ RR's data-derived `meta({ data })` maps to the same push from the LOADER that
136
+ owns the data — `ctx.use(Meta)({ title: data.name })` in the loader body, with
137
+ `loader(Def, { stream: "navigation" })` when the title must be in the SSR'd
138
+ head. See `/loader` → "Writing Handles from Loaders".
139
+
135
140
  Add `<MetaTags />` in the Document component's `<head>`:
136
141
 
137
142
  ```typescript
@@ -40,9 +40,20 @@ Use it only when you need capabilities beyond what the handler provides:
40
40
  to all child routes via `ctx.use(Loader)` or `useLoader(Loader)`
41
41
  - **Independent revalidation** — `revalidate()` on a specific loader after actions
42
42
  - **Per-loader caching** — `loader(L, () => [cache({ ttl: 60 })])`
43
-
44
- If the React Router loader just fetches data for its page component, merge it
45
- into the handler. See `/loader` for when the live data layer is useful.
43
+ - **RR-loader-shaped authority** — a loader that `throw redirect(...)`s or
44
+ throws a 404 keeps that shape: Rango loaders throw `redirect()`/`notFound()`
45
+ too (one caveat: a Rango loader redirect is a client-side navigate on
46
+ document loads, never an HTTP 302 — pre-stream 302s move to middleware)
47
+ - **`meta({ data })` / `handle` exports** — data-derived page metadata becomes
48
+ a handle push from the loader body (`ctx.use(Meta)({ title: data.name })`),
49
+ with `loader(L, { stream: "navigation" })` when it must be in the SSR'd head
50
+
51
+ If the React Router loader just fetches data for its page component AND the
52
+ component can become a server component, merge it into the handler. If the
53
+ component stays a client component, port the whole group with `clientUrls()`
54
+ instead — loader, `useLoader` read, and browser-run `revalidate()` keep the RR
55
+ route-module shape (see the "Two target shapes" section in the main skill and
56
+ `/client-urls`). See `/loader` for when the live data layer is useful.
46
57
 
47
58
  ### Actions
48
59
 
@@ -52,9 +52,12 @@ In framework mode, each route is a file with conventional exports (`loader`,
52
52
  RR7 route module export → Rango equivalent
53
53
  ─────────────────────────────────────────────────────
54
54
  default (Component) → handler in path()
55
- loader → fetch in handler, or createLoader()
55
+ loader → fetch in handler, or createLoader() — a Rango
56
+ loader keeps the RR shape: throw redirect()/
57
+ notFound(), push meta from the body
56
58
  action → "use server" function
57
- meta → ctx.use(Meta) in handler
59
+ meta → ctx.use(Meta) in handler; meta({ data }) →
60
+ ctx.use(Meta) push in the loader that owns data
58
61
  headers → ctx.header() in handler or middleware
59
62
  shouldRevalidate → revalidate() DSL
60
63
  ErrorBoundary → errorBoundary() DSL
@@ -128,6 +131,16 @@ path("/product/:slug", ProductPage, { name: "product" }, () => [
128
131
  Key shift: the route module's scattered exports consolidate into the handler
129
132
  (data fetching, meta, headers) and the DSL (revalidation, error boundary, loading).
130
133
 
134
+ The loader-shaped variant is equally valid — and closer to the RR module when
135
+ the loader carried authority. A `createLoader()` body can throw `notFound()`
136
+ for the missing product AND push the data-derived meta itself
137
+ (`ctx.use(Meta)({ title: product.name })`); register it with
138
+ `loader(ProductLoader, { stream: "navigation" })` when the 404 status and
139
+ title must be in the document deterministically. See `/loader` → "Loader
140
+ Authority" and "Writing Handles from Loaders". (One RR habit that does NOT
141
+ carry over: a loader `throw redirect()` is a client-side navigate on document
142
+ loads, never an HTTP 302 — pre-stream 302s belong in middleware.)
143
+
131
144
  ### RR7 file routing → urls() DSL
132
145
 
133
146
  | RR7 file path | Rango |
@@ -132,9 +132,11 @@ response payload types, use one of these surfaces:
132
132
  // router.tsx
133
133
  export const router = createRouter({ document: Document }).routes(urlpatterns);
134
134
 
135
+ type AppRoutes = typeof router.routeMap;
136
+
135
137
  declare global {
136
138
  namespace Rango {
137
- interface RegisteredRoutes extends typeof router.routeMap {}
139
+ interface RegisteredRoutes extends AppRoutes {}
138
140
  }
139
141
  }
140
142
  ```
@@ -99,7 +99,8 @@ path("/dashboard/:id", (ctx) => {
99
99
  ## Setting Handles (Meta, Breadcrumbs)
100
100
 
101
101
  Parallel slot handlers can call `ctx.use(Meta)` or `ctx.use(Breadcrumbs)` to
102
- push handle data. The data is associated with the **parent** layout or route
102
+ push handle data. (Loader bodies can too see `/loader` "Writing Handles
103
+ from Loaders" — which often replaces the UI-less `@meta` slot below.) The data is associated with the **parent** layout or route
103
104
  segment, not the parallel segment itself. This is because parallels execute
104
105
  after their parent handler and inherit its segment scope.
105
106
 
@@ -130,6 +131,15 @@ route overrides via its own `@meta` slot. Since child segments push after
130
131
  parents and `collectMeta` uses last-wins deduplication, overrides work
131
132
  naturally.
132
133
 
134
+ > **Loader-derived metadata: push from the loader instead.** This slot's
135
+ > `await ctx.use(ProductLoader)` routes the data through HANDLER consumption —
136
+ > the baked lane under `cache()`/PPR — just to reach a `ctx.use(Meta)` call.
137
+ > The loader can now push `Meta` itself (`/loader` → "Writing Handles from
138
+ > Loaders"), keeping the data on the live lane; add
139
+ > `loader(Def, { stream: "navigation" })` when the meta must be in the SSR'd
140
+ > head. Keep the `@meta` slot for metadata that is NOT loader-derived
141
+ > (templates, static descriptions, structured data with independent inputs).
142
+
133
143
  ```typescript
134
144
  // Layout sets defaults
135
145
  layout((ctx) => {
@@ -374,6 +384,27 @@ A `revalidate()` callback may return a hard `boolean`, a soft
374
384
  for the full contract — it's the same across `loader()`, `path()`,
375
385
  `layout()`, `parallel()`, and `intercept()`.
376
386
 
387
+ A route-scoped slot revalidates on ANY params or search change by default —
388
+ including query-only navigations (`?tab=…`) its content doesn't depend on. If
389
+ the slot has no `loading()` of its own, that refresh suspends at the nearest
390
+ boundary above it: the route's `loading()`, replacing the entire route content
391
+ with the route skeleton while one slot refetches. Either scope the slot's
392
+ `revalidate()` (share the route's named contract, as above) or give the slot
393
+ its own `loading()` so the fallback stays local. Don't reach for a bare
394
+ `revalidate(() => false)`: the slot then never refreshes on param changes
395
+ either, and keeps the previous param's content on e.g. a product-to-product
396
+ navigation.
397
+
398
+ `revalidate()` decides whether to _re_-render a slot, never whether to render
399
+ it the first time. A slot the browser has not rendered yet has nothing cached
400
+ to keep showing, so returning `false` for it would just leave a hole. On that
401
+ first render the decision is clamped to `true` and your callback's `false` is
402
+ ignored; from the second visit onward it is honored and the browser keeps the
403
+ copy it already has. This is what makes `revalidate(() => false)` mean "render
404
+ once, then never refetch" rather than "sometimes never appear at all" — before
405
+ the clamp, landing on a sibling route and navigating in left the slot blank
406
+ until a full reload.
407
+
377
408
  ### Revalidation Contracts for Parallel Dependencies
378
409
 
379
410
  Prefer named revalidation contracts shared by both the upstream producer and