@rangojs/router 0.16.0 → 0.17.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.
- package/README.md +254 -89
- package/dist/testing/vitest.js +252 -0
- package/dist/types/browser/navigation-transaction.d.ts +6 -0
- package/dist/types/browser/partial-update.d.ts +11 -0
- package/dist/types/browser/react/ScrollRestoration.d.ts +6 -6
- package/dist/types/browser/rsc-router.d.ts +1 -1
- package/dist/types/browser/scroll-restoration.d.ts +7 -0
- package/dist/types/cache/cache-exec-scope.d.ts +18 -1
- package/dist/types/cache/cache-scope.d.ts +34 -5
- package/dist/types/cache/handle-capture.d.ts +41 -3
- package/dist/types/cache/handle-snapshot.d.ts +53 -13
- package/dist/types/cache/segment-codec.d.ts +10 -3
- package/dist/types/cache/taint.d.ts +1 -1
- package/dist/types/cache/types.d.ts +15 -3
- package/dist/types/client.d.ts +4 -4
- package/dist/types/client.rsc.d.ts +4 -5
- package/dist/types/components/DefaultDocument.d.ts +5 -2
- package/dist/types/context-var.d.ts +6 -5
- package/dist/types/escape-script.d.ts +1 -1
- package/dist/types/handles/MetaTags.d.ts +5 -4
- package/dist/types/handles/Scripts.d.ts +8 -7
- package/dist/types/handles/meta.d.ts +2 -2
- package/dist/types/handles/script.d.ts +17 -16
- package/dist/types/href-client.d.ts +1 -1
- package/dist/types/html.d.ts +12 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +3 -2
- package/dist/types/loader-store.d.ts +7 -4
- package/dist/types/reverse.d.ts +36 -4
- package/dist/types/route-definition/dsl-helpers.d.ts +3 -3
- package/dist/types/route-definition/helpers-types.d.ts +33 -9
- package/dist/types/route-definition/resolve-handler-use.d.ts +23 -1
- package/dist/types/route-types.d.ts +1 -1
- package/dist/types/router/debug-manifest.d.ts +3 -2
- package/dist/types/router/error-handling.d.ts +20 -0
- package/dist/types/router/handler-context.d.ts +6 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +46 -5
- package/dist/types/router/middleware-types.d.ts +3 -2
- package/dist/types/router/router-context.d.ts +3 -1
- package/dist/types/router/router-interfaces.d.ts +24 -2
- package/dist/types/router/router-options.d.ts +8 -5
- package/dist/types/router/segment-resolution/fresh.d.ts +10 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +37 -1
- package/dist/types/router/segment-resolution/loader-mask.d.ts +9 -19
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +3 -3
- package/dist/types/router/segment-resolution/mask-nested.d.ts +7 -7
- package/dist/types/router/segment-resolution/revalidation.d.ts +6 -2
- package/dist/types/router/segment-wrappers.d.ts +1 -1
- package/dist/types/rsc/response-route-handler.d.ts +1 -1
- package/dist/types/rsc/rsc-rendering.d.ts +1 -2
- package/dist/types/rsc/shell-capture-constants.d.ts +8 -0
- package/dist/types/rsc/shell-capture.d.ts +5 -4
- package/dist/types/rsc/ssr-setup.d.ts +6 -6
- package/dist/types/rsc/types.d.ts +10 -0
- package/dist/types/server/context.d.ts +33 -3
- package/dist/types/server/handle-store.d.ts +26 -2
- package/dist/types/server/request-context.d.ts +24 -21
- package/dist/types/ssr/index.d.ts +15 -0
- package/dist/types/static-handler.d.ts +4 -1
- package/dist/types/testing/generated-routes.d.ts +2 -2
- package/dist/types/testing/internal/context.d.ts +1 -1
- package/dist/types/testing/render-route.d.ts +32 -6
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +28 -5
- package/dist/types/testing/vitest.d.ts +35 -1
- package/dist/types/theme/ThemeScript.d.ts +3 -3
- package/dist/types/types/cache-types.d.ts +14 -10
- package/dist/types/types/handler-context.d.ts +14 -0
- package/dist/types/types/loader-types.d.ts +8 -6
- package/dist/types/urls/response-types.d.ts +3 -12
- package/dist/types/use-loader.d.ts +12 -3
- package/dist/types/vite/plugins/use-cache-transform.d.ts +33 -2
- package/dist/types/vite/rango.d.ts +1 -1
- package/dist/vite/index.js +1381 -1346
- package/package.json +2 -2
- package/skills/api-client/SKILL.md +22 -10
- package/skills/breadcrumbs/SKILL.md +65 -22
- package/skills/bundle-analysis/SKILL.md +22 -22
- package/skills/cache-guide/SKILL.md +207 -97
- package/skills/caching/SKILL.md +295 -93
- package/skills/catalog.json +16 -16
- package/skills/client-urls/SKILL.md +53 -31
- package/skills/cloudflare/SKILL.md +72 -20
- package/skills/cloudflare/references/d1-and-local-dev.md +15 -2
- package/skills/cloudflare/references/streaming-and-deploy.md +10 -3
- package/skills/cloudflare/references/webhooks-and-crypto.md +9 -2
- package/skills/comparison/SKILL.md +5 -0
- package/skills/comparison/references/framework-comparison.md +39 -33
- package/skills/composability/SKILL.md +38 -29
- package/skills/css/SKILL.md +10 -13
- package/skills/debug-manifest/SKILL.md +74 -31
- package/skills/defer-hydration/SKILL.md +2 -1
- package/skills/deployment-caching/SKILL.md +6 -1
- package/skills/document-cache/SKILL.md +92 -28
- package/skills/fonts/SKILL.md +16 -8
- package/skills/handler-use/SKILL.md +53 -17
- package/skills/hooks/SKILL.md +28 -20
- package/skills/hooks/data.md +23 -3
- package/skills/hooks/handle-and-actions.md +31 -16
- package/skills/hooks/navigation.md +39 -10
- package/skills/hooks/outlets.md +13 -6
- package/skills/hooks/state.md +37 -15
- package/skills/hooks/urls.md +7 -5
- package/skills/host-router/SKILL.md +64 -12
- package/skills/i18n/SKILL.md +60 -34
- package/skills/intercept/SKILL.md +161 -26
- package/skills/layout/SKILL.md +106 -50
- package/skills/links/SKILL.md +51 -19
- package/skills/loader/SKILL.md +242 -106
- package/skills/middleware/SKILL.md +119 -23
- package/skills/migrate-nextjs/SKILL.md +100 -45
- package/skills/migrate-nextjs/backend-host-swap.md +5 -2
- package/skills/migrate-react-router/SKILL.md +49 -38
- package/skills/migrate-react-router/component-migration.md +25 -6
- package/skills/migrate-react-router/data-and-actions.md +18 -5
- package/skills/migrate-react-router/route-mapping.md +12 -6
- package/skills/mime-routes/SKILL.md +12 -7
- package/skills/observability/SKILL.md +28 -14
- package/skills/parallel/SKILL.md +75 -39
- package/skills/ppr/SKILL.md +345 -150
- package/skills/prerender/SKILL.md +189 -100
- package/skills/rango/SKILL.md +65 -34
- package/skills/react-compiler/SKILL.md +6 -5
- package/skills/response-routes/SKILL.md +133 -25
- package/skills/route/SKILL.md +165 -60
- package/skills/router-setup/SKILL.md +418 -240
- package/skills/scripts/SKILL.md +31 -20
- package/skills/server-actions/SKILL.md +220 -59
- package/skills/shell-manifest/SKILL.md +12 -7
- package/skills/streams-and-websockets/SKILL.md +32 -14
- package/skills/tailwind/SKILL.md +37 -33
- package/skills/testing/SKILL.md +68 -32
- package/skills/testing/cache-prerender.md +55 -29
- package/skills/testing/client-components.md +59 -6
- package/skills/testing/e2e-parity.md +12 -2
- package/skills/testing/flight.md +19 -11
- package/skills/testing/handles.md +8 -5
- package/skills/testing/loader.md +8 -5
- package/skills/testing/middleware.md +8 -3
- package/skills/testing/predicates.md +120 -0
- package/skills/testing/render-handler.md +70 -22
- package/skills/testing/response-routes.md +11 -4
- package/skills/testing/reverse-and-types.md +20 -14
- package/skills/testing/server-actions.md +12 -3
- package/skills/testing/server-tree.md +9 -0
- package/skills/testing/setup.md +9 -5
- package/skills/theme/SKILL.md +106 -29
- package/skills/typesafety/SKILL.md +20 -9
- package/skills/typesafety/env-and-bindings.md +126 -47
- package/skills/typesafety/generated-files-and-cli.md +26 -14
- package/skills/typesafety/params-and-search.md +44 -19
- package/skills/typesafety/route-types.md +50 -14
- package/skills/use-cache/SKILL.md +200 -82
- package/skills/vercel/SKILL.md +21 -11
- package/skills/view-transitions/SKILL.md +41 -20
- package/src/__augment-tests__/augmented.check.ts +26 -1
- package/src/browser/index.ts +2 -2
- package/src/browser/navigation-bridge.ts +3 -4
- package/src/browser/navigation-transaction.ts +22 -2
- package/src/browser/partial-update.ts +35 -25
- package/src/browser/react/ScrollRestoration.tsx +6 -6
- package/src/browser/rsc-router.tsx +1 -1
- package/src/browser/scroll-restoration.ts +53 -6
- package/src/cache/cache-exec-scope.ts +37 -4
- package/src/cache/cache-key-utils.ts +1 -6
- package/src/cache/cache-runtime.ts +230 -61
- package/src/cache/cache-scope.ts +76 -12
- package/src/cache/document-cache.ts +15 -0
- package/src/cache/handle-capture.ts +90 -10
- package/src/cache/handle-snapshot.ts +132 -28
- package/src/cache/segment-codec.ts +26 -7
- package/src/cache/tag-invalidation.ts +4 -3
- package/src/cache/taint.ts +1 -1
- package/src/cache/types.ts +16 -3
- package/src/client.rsc.tsx +10 -9
- package/src/client.tsx +5 -4
- package/src/components/DefaultDocument.tsx +7 -2
- package/src/context-var.ts +6 -5
- package/src/escape-script.ts +1 -1
- package/src/handles/MetaTags.tsx +13 -11
- package/src/handles/Scripts.tsx +11 -10
- package/src/handles/meta.ts +2 -2
- package/src/handles/script.ts +17 -16
- package/src/href-client.ts +1 -1
- package/src/html.ts +12 -0
- package/src/index.rsc.ts +5 -0
- package/src/index.ts +1 -0
- package/src/loader-store.ts +7 -4
- package/src/prerender/build-shell-capture.ts +8 -11
- package/src/reverse.ts +44 -4
- package/src/route-definition/dsl-helpers.ts +117 -30
- package/src/route-definition/helpers-types.ts +33 -9
- package/src/route-definition/resolve-handler-use.ts +121 -6
- package/src/route-types.ts +0 -3
- package/src/router/debug-manifest.ts +10 -2
- package/src/router/error-handling.ts +51 -15
- package/src/router/handler-context.ts +34 -25
- package/src/router/intercept-resolution.ts +125 -39
- package/src/router/loader-resolution.ts +56 -11
- package/src/router/match-api.ts +12 -17
- package/src/router/match-middleware/background-revalidation.ts +161 -96
- package/src/router/match-middleware/cache-lookup.ts +93 -10
- package/src/router/match-middleware/cache-store.ts +17 -90
- package/src/router/middleware-types.ts +3 -5
- package/src/router/middleware.ts +52 -9
- package/src/router/prerender-match.ts +53 -19
- package/src/router/route-snapshot.ts +11 -1
- package/src/router/router-context.ts +2 -0
- package/src/router/router-interfaces.ts +25 -2
- package/src/router/router-options.ts +8 -5
- package/src/router/segment-resolution/fresh.ts +44 -12
- package/src/router/segment-resolution/loader-cache.ts +205 -45
- package/src/router/segment-resolution/loader-mask.ts +12 -22
- package/src/router/segment-resolution/loader-snapshot.ts +6 -6
- package/src/router/segment-resolution/mask-nested.ts +7 -7
- package/src/router/segment-resolution/revalidation.ts +34 -6
- package/src/router/segment-wrappers.ts +4 -0
- package/src/rsc/render-pipeline.ts +3 -0
- package/src/rsc/response-route-handler.ts +11 -3
- package/src/rsc/rsc-rendering.ts +8 -45
- package/src/rsc/shell-capture-constants.ts +13 -0
- package/src/rsc/shell-capture.ts +111 -90
- package/src/rsc/ssr-setup.ts +14 -8
- package/src/rsc/types.ts +11 -0
- package/src/server/context.ts +88 -11
- package/src/server/cookie-store.ts +5 -4
- package/src/server/handle-store.ts +232 -7
- package/src/server/request-context.ts +35 -30
- package/src/ssr/index.tsx +40 -7
- package/src/static-handler.ts +4 -1
- package/src/testing/flight-runtime.d.ts +21 -0
- package/src/testing/generated-routes.ts +2 -2
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/internal/flight-client-globals.ts +7 -5
- package/src/testing/render-route.tsx +85 -24
- package/src/testing/run-loader.ts +5 -1
- package/src/testing/vitest-stubs/plugin-rsc.ts +123 -20
- package/src/testing/vitest.ts +62 -1
- package/src/theme/ThemeScript.tsx +3 -3
- package/src/types/cache-types.ts +14 -10
- package/src/types/handler-context.ts +14 -0
- package/src/types/loader-types.ts +8 -6
- package/src/urls/response-types.ts +3 -23
- package/src/use-loader.tsx +12 -3
- package/src/vite/plugins/use-cache-transform.ts +118 -74
- package/src/vite/rango.ts +7 -3
package/skills/links/SKILL.md
CHANGED
|
@@ -6,9 +6,12 @@ argument-hint: [ctx.reverse|href|useHref|useMount|useReverse|scopedReverse]
|
|
|
6
6
|
|
|
7
7
|
# Links & URL Generation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use this skill to generate URLs to your own routes by name (server) or by
|
|
10
|
+
typed path (client), and to keep links correct when a module is mounted under
|
|
11
|
+
a different `include()` prefix. For route typing setup see `/typesafety`; for
|
|
12
|
+
links to JSON/text endpoints see `/response-routes`.
|
|
10
13
|
|
|
11
|
-
**Default server API: `ctx.reverse()`.** Generate URLs from the handler context — it's typed, auto-fills
|
|
14
|
+
**Default server API: `ctx.reverse()`.** Generate URLs from the handler context — it's typed, auto-fills params from the current request, and resolves local (`.name`) and global (`name`) names. In middleware and response routes it takes global names only (see below).
|
|
12
15
|
|
|
13
16
|
**On the client, two patterns:**
|
|
14
17
|
|
|
@@ -19,10 +22,19 @@ argument-hint: [ctx.reverse|href|useHref|useMount|useReverse|scopedReverse]
|
|
|
19
22
|
|
|
20
23
|
## Server: ctx.reverse()
|
|
21
24
|
|
|
22
|
-
Available
|
|
25
|
+
Available on the handler context (route handlers, layouts, parallels), on
|
|
26
|
+
middleware and loader contexts, and on `getRequestContext()` inside server
|
|
27
|
+
actions. Resolves named routes using the full route map. This is the default
|
|
28
|
+
way to generate URLs on the server. Patterns in the map already include the
|
|
29
|
+
router `basename`, so results are basename-prefixed.
|
|
30
|
+
|
|
31
|
+
Middleware and response routes (`path.json()`, `path.text()`, …) get a
|
|
32
|
+
global-only `ctx.reverse` (`GlobalReverseFunction`): no `include()` scope and no
|
|
33
|
+
param auto-fill, so pass the fully qualified name and every param. A dot-local
|
|
34
|
+
`.name` is a type error there. See `/middleware` and `/response-routes`.
|
|
23
35
|
|
|
24
36
|
```typescript
|
|
25
|
-
import { urls
|
|
37
|
+
import { urls } from "@rangojs/router";
|
|
26
38
|
|
|
27
39
|
export const shopPatterns = urls(({ path, layout }) => [
|
|
28
40
|
layout(<ShopLayout />, () => [
|
|
@@ -63,7 +75,7 @@ path("/product/:slug", (ctx) => {
|
|
|
63
75
|
|
|
64
76
|
### Local names (dot-prefixed)
|
|
65
77
|
|
|
66
|
-
Prefix a name with `.` to resolve it within the current `include()` scope. The route is looked up using the include's mount namespace.
|
|
78
|
+
Prefix a name with `.` to resolve it within the current `include()` scope. The route is looked up using the include's mount namespace. If the name is not found there, lookup walks up the enclosing include scopes (`shop.admin.x`, then `shop.x`). It falls back to a bare root-level name only for root-scoped routes (top-level routes and routes under `{ name: "" }` mounts); inside a named mount, a dot-local name never leaks into unrelated global names.
|
|
67
79
|
|
|
68
80
|
```typescript
|
|
69
81
|
// urls/magazine.tsx — mounted at include("/magazine", magazinePatterns, { name: "magazine" })
|
|
@@ -97,7 +109,7 @@ export const tenantPatterns = urls(({ path }) => [
|
|
|
97
109
|
]);
|
|
98
110
|
```
|
|
99
111
|
|
|
100
|
-
Auto-fill uses `{ ...ctx.params, ...hrefParams }` — current request params are defaults, explicit params win. Params not needed by the target route are silently ignored.
|
|
112
|
+
Auto-fill uses `{ ...ctx.params, ...hrefParams }` — current request params are defaults, explicit params win. Params not needed by the target route are silently ignored. Because every current param is a default, drop an optional one explicitly with `undefined` or `""` — under `include("/:locale?", ...)` on `/en/...`, a bare `ctx.reverse("menu.index")` keeps `/en`, while `ctx.reverse("menu.index", { locale: undefined })` returns `/` (see `/i18n`). A missing required param throws `Missing param "slug" for route "…"`; an unknown name throws `Unknown route: "…"`.
|
|
101
113
|
|
|
102
114
|
### Global names (unprefixed)
|
|
103
115
|
|
|
@@ -112,7 +124,7 @@ Unprefixed names resolve against the full named-routes map (the generated `route
|
|
|
112
124
|
|
|
113
125
|
### reverse with search params
|
|
114
126
|
|
|
115
|
-
When a route has a `search` schema, pass a typed search object as the third argument:
|
|
127
|
+
When a route has a `search` schema, pass a typed search object as the third argument. `undefined`/`null` values are skipped; keys keep insertion order:
|
|
116
128
|
|
|
117
129
|
```typescript
|
|
118
130
|
path("/search", (ctx) => {
|
|
@@ -124,7 +136,7 @@ path("/search", (ctx) => {
|
|
|
124
136
|
|
|
125
137
|
### scopedReverse() - type-safe ctx.reverse
|
|
126
138
|
|
|
127
|
-
Wraps `ctx.reverse` with local route
|
|
139
|
+
Wraps `ctx.reverse` with the module's local route types for autocomplete and validation. Runtime behavior is identical to `ctx.reverse` — `scopedReverse` is a type-only cast, and it also works on loader contexts. Don't use it on middleware or response-route contexts: their `ctx.reverse` has no `include()` scope, so the local names it types would throw `Unknown route`. Always call local names with the dot: the returned function is typed only against the module's local map, so an unprefixed local name (`reverse("cart")`) type-checks but is resolved as a global name at runtime — it throws `Unknown route` unless a global route of that exact name happens to exist.
|
|
128
140
|
|
|
129
141
|
```typescript
|
|
130
142
|
import { scopedReverse } from "@rangojs/router";
|
|
@@ -134,12 +146,15 @@ path("/product/:slug", (ctx) => {
|
|
|
134
146
|
|
|
135
147
|
reverse(".cart"); // Local name (dot-prefixed) — resolves in include scope
|
|
136
148
|
reverse(".product", { slug: "widget" }); // Local name with params
|
|
137
|
-
|
|
149
|
+
|
|
150
|
+
ctx.reverse("blog.post", { slug: "hi" }); // Global names: call ctx.reverse directly
|
|
138
151
|
|
|
139
152
|
return <ProductPage slug={ctx.params.slug} />;
|
|
140
153
|
}, { name: "product" })
|
|
141
154
|
```
|
|
142
155
|
|
|
156
|
+
To type local and global names on one function, type the handler with the module's generated map instead: `Handler<"shop.product", routes>` (see `/typesafety`).
|
|
157
|
+
|
|
143
158
|
`reverse()` does not accept raw path strings (`"/about"`). For static paths in client components, use `href("/about")`; on the server, look up the route by name.
|
|
144
159
|
|
|
145
160
|
## Client components: receive URLs as props
|
|
@@ -150,9 +165,12 @@ path("/product/:slug", (ctx) => {
|
|
|
150
165
|
|
|
151
166
|
```tsx
|
|
152
167
|
// server
|
|
153
|
-
|
|
168
|
+
import type { Handler } from "@rangojs/router";
|
|
169
|
+
import { ShareButton } from "./share-button";
|
|
170
|
+
|
|
171
|
+
export const BlogPostPage: Handler<{ slug: string }> = (ctx) => {
|
|
154
172
|
return <ShareButton url={ctx.reverse(".post", { slug: ctx.params.slug })} />;
|
|
155
|
-
}
|
|
173
|
+
};
|
|
156
174
|
```
|
|
157
175
|
|
|
158
176
|
```tsx
|
|
@@ -169,6 +187,8 @@ export function ShareButton({ url }: { url: string }) {
|
|
|
169
187
|
|
|
170
188
|
```tsx
|
|
171
189
|
// server — loaders/nav.ts
|
|
190
|
+
import { createLoader } from "@rangojs/router";
|
|
191
|
+
|
|
172
192
|
export const NavLoader = createLoader((ctx) => ({
|
|
173
193
|
home: ctx.reverse("home"),
|
|
174
194
|
blog: ctx.reverse("blog.index"),
|
|
@@ -182,6 +202,8 @@ const urlpatterns = urls(({ path, loader }) => [
|
|
|
182
202
|
|
|
183
203
|
```tsx
|
|
184
204
|
"use client";
|
|
205
|
+
import { Link, useLoader } from "@rangojs/router/client";
|
|
206
|
+
import { NavLoader } from "../loaders/nav";
|
|
185
207
|
|
|
186
208
|
function Nav() {
|
|
187
209
|
const { data } = useLoader(NavLoader);
|
|
@@ -195,6 +217,7 @@ function Nav() {
|
|
|
195
217
|
|
|
196
218
|
```tsx
|
|
197
219
|
"use server";
|
|
220
|
+
import { getRequestContext } from "@rangojs/router";
|
|
198
221
|
|
|
199
222
|
export async function getProductUrl(slug: string) {
|
|
200
223
|
const ctx = getRequestContext();
|
|
@@ -237,7 +260,9 @@ import { href } from "@rangojs/router/client";
|
|
|
237
260
|
export const appHref = (path: Rango.Path): string => href(path);
|
|
238
261
|
```
|
|
239
262
|
|
|
240
|
-
`href()` is a raw path helper — it is **not** basename-aware. It returns the path as-is (or with the include mount prefix via `useHref()`).
|
|
263
|
+
`href()` is a raw path helper — it is **not** basename-aware. It returns the path as-is (or with the include mount prefix via `useHref()`). `<Link to={href("/about")}>` still lands on the basename-prefixed URL because `Link` and `useRouter().push()` prefix root-relative paths with the router's basename; a plain `<a href>`, `fetch()`, or `window.location` gets the raw path. On the server, `ctx.reverse()` output is already basename-prefixed.
|
|
264
|
+
|
|
265
|
+
`href.json()`, `href.text()`, `href.html()`, `href.xml()`, `href.md()`, `href.image()`, `href.stream()` and `href.any()` return `{ to, "data-external": "" }` props for linking to response routes with a hard navigation — see `/response-routes`.
|
|
241
266
|
|
|
242
267
|
## Client: useHref()
|
|
243
268
|
|
|
@@ -263,6 +288,8 @@ function ShopNav() {
|
|
|
263
288
|
|
|
264
289
|
Use `useHref()` for local navigation within a mounted module. Use the bare `href()` function for absolute paths outside the current mount.
|
|
265
290
|
|
|
291
|
+
`useHref()` concatenates the mount **pattern** as-is and does not substitute params, and its argument is not checked against your routes. Under a parameterized mount (`include("/tenant/:tenantId", ...)`) it would produce `/tenant/:tenantId/cart` — use `useReverse(routes)` there, which substitutes mount params from `useParams()`.
|
|
292
|
+
|
|
266
293
|
## Client: useMount()
|
|
267
294
|
|
|
268
295
|
Returns the current `include()` mount path. Useful for building custom logic based on mount location.
|
|
@@ -279,7 +306,7 @@ function MountInfo() {
|
|
|
279
306
|
}
|
|
280
307
|
```
|
|
281
308
|
|
|
282
|
-
`useMount()` reads from `MountContext`, which is automatically set by `include()` in the segment tree.
|
|
309
|
+
`useMount()` reads from `MountContext`, which is automatically set by `include()` in the segment tree. Nested includes return the nearest mount's full URL prefix (e.g. `/shop/admin`), and a parameterized include returns its pattern (`/tenant/:tenantId`), not the matched URL. `href(path, mount)` is the non-hook equivalent of `useHref()`.
|
|
283
310
|
|
|
284
311
|
## Client: useReverse(routes)
|
|
285
312
|
|
|
@@ -309,7 +336,9 @@ export function BlogNav() {
|
|
|
309
336
|
1. Strips an optional leading `.` and looks up the name in the imported `routes` map.
|
|
310
337
|
2. Joins the local pattern with the surrounding `useMount()` value — the include's URL pattern.
|
|
311
338
|
3. Substitutes params: explicit params from the call, then auto-filled from `useParams()` for anything still unresolved (mount params like `:tenantId` flow in this way).
|
|
312
|
-
4. Appends a query string
|
|
339
|
+
4. Appends a query string when a search object is passed (typed from the route's `search` schema; `undefined`/`null` values are skipped).
|
|
340
|
+
|
|
341
|
+
The returned function is memoized on the routes map, mount, and current params, so it is safe to pass to memoized children.
|
|
313
342
|
|
|
314
343
|
### Mount-relativity
|
|
315
344
|
|
|
@@ -337,13 +366,16 @@ The `/` pattern under a non-root mount collapses cleanly: under `/news`, `revers
|
|
|
337
366
|
When the include itself carries `:params`, those are auto-filled from `useParams()` so the caller doesn't have to thread them through:
|
|
338
367
|
|
|
339
368
|
```typescript
|
|
369
|
+
// urls/tenant.tsx: index "/" and post "/posts/:postId"
|
|
340
370
|
// urls.tsx
|
|
341
|
-
include("/tenant/:tenantId",
|
|
371
|
+
include("/tenant/:tenantId", tenantPatterns, { name: "tenant" });
|
|
342
372
|
```
|
|
343
373
|
|
|
344
374
|
```tsx
|
|
375
|
+
import { routes as tenantRoutes } from "../urls/tenant.gen.js";
|
|
376
|
+
|
|
345
377
|
// At /tenant/acme/posts/p1, useParams() = { tenantId: "acme", postId: "p1" }
|
|
346
|
-
const reverse = useReverse(
|
|
378
|
+
const reverse = useReverse(tenantRoutes);
|
|
347
379
|
|
|
348
380
|
reverse(".index"); // "/tenant/acme"
|
|
349
381
|
reverse(".post", { postId: "p2" }); // "/tenant/acme/posts/p2" (tenantId auto-filled)
|
|
@@ -411,7 +443,7 @@ pnpm exec rango generate src/urls --static
|
|
|
411
443
|
|
|
412
444
|
Don't edit the file by hand — re-run codegen when patterns change.
|
|
413
445
|
|
|
414
|
-
**
|
|
446
|
+
**The Vite plugin only regenerates the router-level `*.named-routes.gen.ts`.** Per-module `urls/*.gen.ts` files are emitted only by the `rango generate` CLI. Commit the generated files and re-run `rango generate` whenever a `urls()` module's `path()`/`include()` shape changes. `clientUrls()` modules get a `.gen.ts` the same way. A common workflow is to wire it into a `predev` script:
|
|
415
447
|
|
|
416
448
|
```jsonc
|
|
417
449
|
// package.json
|
|
@@ -452,7 +484,7 @@ queued or in flight; removing it re-arms both Link types.
|
|
|
452
484
|
| Context | API | Resolves | Use for |
|
|
453
485
|
| ---------------- | -------------------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------- |
|
|
454
486
|
| Server handler | `ctx.reverse("name")` | Named routes (local + absolute) | **Default** server-side URL generation |
|
|
455
|
-
| Server handler | `scopedReverse<T>(ctx.reverse)` |
|
|
487
|
+
| Server handler | `scopedReverse<T>(ctx.reverse)` | Local `.name` routes, typed from `T` | Type-safe in-module server URLs |
|
|
456
488
|
| Client component | `useReverse(routes)` | Local names from an imported `routes` map | Typed in-module URL generation without round-tripping the server |
|
|
457
489
|
| Client component | (URL passed as prop / loader data / action return) | Named routes | Cross-module URLs or one-off names you don't want to import |
|
|
458
490
|
| Client component | `href("/path")` | Absolute paths (static strings) | Static navigation where no named-route lookup is needed |
|
|
@@ -470,7 +502,7 @@ import { urls, scopedReverse } from "@rangojs/router";
|
|
|
470
502
|
export const shopPatterns = urls(({ path, layout }) => [
|
|
471
503
|
layout((ctx) => {
|
|
472
504
|
const reverse = scopedReverse<typeof shopPatterns>(ctx.reverse);
|
|
473
|
-
return <ShopLayout cartUrl={reverse("cart")} />;
|
|
505
|
+
return <ShopLayout cartUrl={reverse(".cart")} />;
|
|
474
506
|
}, () => [
|
|
475
507
|
path("/", ShopIndex, { name: "index" }),
|
|
476
508
|
path("/cart", CartPage, { name: "cart" }),
|