@rangojs/router 0.0.0-experimental.bd6e11bc → 0.0.0-experimental.bdaf10aa
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/AGENTS.md +8 -4
- package/README.md +296 -887
- package/dist/bin/rango.js +459 -91
- package/dist/testing/vitest.js +36 -2
- package/dist/vite/index.js +1708 -414
- package/package.json +35 -10
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +82 -5
- package/skills/bundle-analysis/SKILL.md +2 -2
- package/skills/cache-guide/SKILL.md +14 -9
- package/skills/caching/SKILL.md +221 -12
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +83 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +11 -3
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +9 -9
- package/skills/hooks/SKILL.md +73 -900
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +84 -7
- package/skills/i18n/SKILL.md +1 -1
- package/skills/intercept/SKILL.md +51 -17
- package/skills/layout/SKILL.md +38 -16
- package/skills/links/SKILL.md +1 -1
- package/skills/loader/SKILL.md +48 -20
- package/skills/middleware/SKILL.md +11 -5
- package/skills/migrate-nextjs/SKILL.md +203 -20
- package/skills/migrate-react-router/SKILL.md +59 -675
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +3 -3
- package/skills/observability/SKILL.md +70 -5
- package/skills/parallel/SKILL.md +32 -8
- package/skills/ppr/SKILL.md +622 -0
- package/skills/prerender/SKILL.md +59 -28
- package/skills/rango/SKILL.md +124 -50
- package/skills/response-routes/SKILL.md +78 -46
- package/skills/route/SKILL.md +85 -6
- package/skills/router-setup/SKILL.md +41 -6
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +28 -3
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +1 -1
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +68 -654
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +45 -918
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +47 -17
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +44 -1
- package/src/__augment-tests__/augmented.check.ts +2 -3
- package/src/__internal.ts +0 -65
- package/src/browser/action-coordinator.ts +1 -1
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +14 -27
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +178 -100
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +81 -68
- package/src/browser/navigation-client.ts +115 -70
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +153 -88
- package/src/browser/navigation-transaction.ts +0 -32
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +157 -144
- package/src/browser/prefetch/cache.ts +148 -81
- package/src/browser/prefetch/fetch.ts +231 -51
- package/src/browser/prefetch/queue.ts +25 -7
- package/src/browser/rango-state.ts +157 -115
- package/src/browser/react/Link.tsx +40 -7
- package/src/browser/react/NavigationProvider.tsx +140 -99
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +17 -2
- package/src/browser/react/index.ts +0 -51
- package/src/browser/react/location-state-shared.ts +14 -15
- package/src/browser/react/location-state.ts +0 -1
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +0 -5
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +10 -5
- package/src/browser/react/use-params.ts +0 -2
- package/src/browser/react/use-router.ts +6 -4
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +0 -13
- package/src/browser/response-adapter.ts +74 -8
- package/src/browser/rsc-router.tsx +97 -22
- package/src/browser/scroll-restoration.ts +15 -8
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/server-action-bridge.ts +216 -38
- package/src/browser/types.ts +94 -22
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/generate-manifest.ts +155 -131
- package/src/build/generate-route-types.ts +1 -1
- package/src/build/index.ts +11 -5
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -22
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +12 -1
- package/src/build/route-types/include-resolution.ts +455 -61
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +15 -2
- package/src/build/route-types/router-processing.ts +77 -41
- package/src/build/route-types/source-scan.ts +105 -7
- package/src/build/runtime-discovery.ts +4 -1
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +454 -101
- package/src/cache/cache-scope.ts +159 -54
- package/src/cache/cache-tag.ts +149 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2170 -377
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +194 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1132 -0
- package/src/client.rsc.tsx +39 -22
- package/src/client.tsx +28 -58
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +13 -1
- package/src/decode-loader-results.ts +18 -2
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +0 -3
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +57 -40
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +7 -0
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +1 -65
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +6 -2
- package/src/href-client.ts +7 -12
- package/src/index.rsc.ts +88 -8
- package/src/index.ts +90 -16
- package/src/internal-debug.ts +11 -10
- package/src/loader.rsc.ts +19 -9
- package/src/loader.ts +12 -4
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +32 -37
- package/src/prerender.ts +75 -7
- package/src/redirect-origin.ts +114 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +25 -0
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +13 -49
- package/src/route-definition/dsl-helpers.ts +60 -53
- package/src/route-definition/helper-factories.ts +0 -2
- package/src/route-definition/helpers-types.ts +46 -46
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +6 -1
- package/src/route-definition/use-item-types.ts +3 -6
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +0 -5
- package/src/router/content-negotiation.ts +58 -23
- package/src/router/error-handling.ts +44 -17
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +6 -1
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +35 -2
- package/src/router/lazy-includes.ts +79 -56
- package/src/router/loader-resolution.ts +151 -73
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +76 -52
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +181 -178
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +115 -194
- package/src/router/match-middleware/cache-store.ts +61 -50
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +36 -67
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +0 -116
- package/src/router/middleware.ts +231 -120
- package/src/router/navigation-snapshot.ts +7 -56
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +99 -152
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +111 -66
- package/src/router/preview-match.ts +3 -1
- package/src/router/request-classification.ts +47 -42
- package/src/router/revalidation.ts +75 -81
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +70 -8
- package/src/router/router-options.ts +126 -4
- package/src/router/segment-resolution/fresh.ts +104 -80
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +155 -39
- package/src/router/segment-resolution/loader-mask.ts +60 -0
- package/src/router/segment-resolution/loader-snapshot.ts +259 -0
- package/src/router/segment-resolution/mask-nested.ts +83 -0
- package/src/router/segment-resolution/revalidation.ts +215 -304
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +35 -15
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +54 -35
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +9 -23
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -64
- package/src/router/types.ts +1 -63
- package/src/router/url-params.ts +13 -5
- package/src/router.ts +119 -48
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +1 -0
- package/src/rsc/handler.ts +267 -152
- package/src/rsc/helpers.ts +78 -4
- package/src/rsc/index.ts +1 -4
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +114 -38
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +11 -15
- package/src/rsc/progressive-enhancement.ts +120 -13
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +58 -141
- package/src/rsc/rsc-rendering.ts +492 -49
- package/src/rsc/runtime-warnings.ts +14 -0
- package/src/rsc/server-action.ts +268 -82
- package/src/rsc/shell-capture.ts +1190 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +45 -3
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +31 -26
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +260 -95
- package/src/server/context.ts +99 -9
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +125 -2
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +379 -138
- package/src/ssr/index.tsx +491 -182
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +44 -48
- package/src/testing/collect-handle.ts +14 -31
- package/src/testing/dispatch.ts +533 -160
- package/src/testing/e2e/fixture.ts +45 -11
- package/src/testing/e2e/index.ts +1 -22
- package/src/testing/e2e/matchers.ts +0 -16
- package/src/testing/e2e/parity.ts +85 -4
- package/src/testing/e2e/server.ts +12 -0
- package/src/testing/flight-matchers.ts +7 -14
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +36 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +30 -0
- package/src/testing/flight.ts +145 -70
- package/src/testing/generated-routes.ts +26 -50
- package/src/testing/index.ts +18 -19
- package/src/testing/internal/context.ts +184 -68
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +134 -115
- package/src/testing/run-loader.ts +140 -51
- package/src/testing/run-middleware.ts +59 -33
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +1 -1
- package/src/testing/vitest-stubs/cloudflare-workers.ts +1 -1
- package/src/testing/vitest.ts +138 -16
- package/src/theme/ThemeProvider.tsx +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +15 -15
- package/src/types/handler-context.ts +45 -15
- package/src/types/index.ts +2 -10
- package/src/types/loader-types.ts +6 -3
- package/src/types/request-scope.ts +8 -22
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +100 -13
- package/src/urls/include-helper.ts +10 -12
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -8
- package/src/urls/path-helper-types.ts +52 -14
- package/src/urls/path-helper.ts +5 -54
- package/src/urls/pattern-types.ts +36 -0
- package/src/urls/type-extraction.ts +76 -42
- package/src/urls/urls-function.ts +0 -14
- package/src/use-loader.tsx +0 -186
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/discovery/bundle-postprocess.ts +2 -1
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +34 -43
- package/src/vite/discovery/discovery-errors.ts +61 -0
- package/src/vite/discovery/prerender-collection.ts +33 -46
- package/src/vite/discovery/state.ts +12 -1
- package/src/vite/discovery/virtual-module-codegen.ts +1 -11
- package/src/vite/index.ts +9 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +143 -10
- package/src/vite/plugins/cjs-to-esm.ts +8 -12
- package/src/vite/plugins/client-ref-dedup.ts +0 -11
- package/src/vite/plugins/client-ref-hashing.ts +0 -10
- package/src/vite/plugins/cloudflare-protocol-stub.ts +0 -20
- package/src/vite/plugins/expose-action-id.ts +2 -73
- package/src/vite/plugins/expose-id-utils.ts +85 -56
- package/src/vite/plugins/expose-ids/export-analysis.ts +30 -43
- package/src/vite/plugins/expose-ids/handler-transform.ts +5 -31
- package/src/vite/plugins/expose-ids/loader-transform.ts +12 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +98 -26
- package/src/vite/plugins/expose-internal-ids.ts +10 -1
- package/src/vite/plugins/performance-tracks.ts +0 -3
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +21 -46
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +22 -27
- package/src/vite/plugins/version-plugin.ts +6 -66
- package/src/vite/plugins/virtual-entries.ts +137 -26
- package/src/vite/rango.ts +146 -135
- package/src/vite/router-discovery.ts +189 -48
- package/src/vite/utils/ast-handler-extract.ts +11 -20
- package/src/vite/utils/bundle-analysis.ts +6 -13
- package/src/vite/utils/client-chunks.ts +0 -6
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +0 -22
- package/src/vite/utils/manifest-utils.ts +4 -75
- package/src/vite/utils/package-resolution.ts +1 -73
- package/src/vite/utils/prerender-utils.ts +71 -44
- package/src/vite/utils/shared-utils.ts +55 -37
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prerender
|
|
3
|
-
description: Pre-render route segments at build time with Prerender and Passthrough live fallback
|
|
3
|
+
description: Pre-render route segments at build time with Prerender and Passthrough live fallback. Use when a page's content is mostly static and shouldn't render on every request, speeding up cold responses, or deciding which routes to prerender vs render live.
|
|
4
4
|
argument-hint: [passthrough]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -11,6 +11,13 @@ deserialization path, same segment system. The worker handles every request --
|
|
|
11
11
|
there are NO static .html or .rsc files served from assets. The worker reads
|
|
12
12
|
pre-computed Flight payloads instead of executing handler code.
|
|
13
13
|
|
|
14
|
+
## Not this skill if…
|
|
15
|
+
|
|
16
|
+
- You want a cached HTML shell captured at runtime, with holes and loaders
|
|
17
|
+
staying live per request — see `/ppr`.
|
|
18
|
+
- You want runtime segment caching with TTL/SWR — that is the `cache()` DSL:
|
|
19
|
+
see `/caching`. Prerender is the same cache filled at build time.
|
|
20
|
+
|
|
14
21
|
## API: Prerender
|
|
15
22
|
|
|
16
23
|
### Static Route (no params)
|
|
@@ -119,6 +126,8 @@ interface BuildContext<TParams> {
|
|
|
119
126
|
use: <T>(handle: Handle<T>) => (data: T) => void; // Push handle data
|
|
120
127
|
url: URL; // Synthetic URL from pattern + params
|
|
121
128
|
pathname: string; // Pathname from synthetic URL
|
|
129
|
+
searchParams: URLSearchParams; // URLSearchParams from the synthetic URL (always empty for prerender)
|
|
130
|
+
search: {}; // Typed search params -- always {} for prerender (no real query string)
|
|
122
131
|
set(key: string, value: any): void; // Set context variable (string key)
|
|
123
132
|
set<T>(contextVar: ContextVar<T>, value: T): void; // Set typed context variable
|
|
124
133
|
get(key: string): any; // Read context variable (string key)
|
|
@@ -241,16 +250,16 @@ path("/blog/:slug", BlogPost, { name: "blog.post" }, () => [
|
|
|
241
250
|
|
|
242
251
|
## Interaction with DSL Items
|
|
243
252
|
|
|
244
|
-
| DSL item | Behavior with Prerender
|
|
245
|
-
| -------------- |
|
|
246
|
-
| `loader()` | Live at runtime, bundled normally. Use `cache()` for caching.
|
|
247
|
-
| `revalidate()` | Not allowed without Passthrough. Allowed with Passthrough.
|
|
248
|
-
| `cache()` | Orthogonal -- use on parent layouts and loaders.
|
|
249
|
-
| `layout()` | Child layouts inside path are pre-rendered. Parent layouts are live.
|
|
250
|
-
| `parallel()` | Parallel slots inside path are pre-rendered.
|
|
251
|
-
| `middleware()` | Skipped during pre-render (no request). Runs at request time for loaders.
|
|
252
|
-
| `loading()` | Ignored without Passthrough. Works for live fallback with Passthrough.
|
|
253
|
-
| `intercept()` | Pre-rendered at build time. Intercept variant stored under `/i` key alongside main segments. At runtime, the correct variant is served based on `ctx.isIntercept`. `when
|
|
253
|
+
| DSL item | Behavior with Prerender |
|
|
254
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
255
|
+
| `loader()` | Live at runtime, bundled normally. Use `cache()` for caching. |
|
|
256
|
+
| `revalidate()` | Not allowed without Passthrough. Allowed with Passthrough. |
|
|
257
|
+
| `cache()` | Orthogonal -- use on parent layouts and loaders. |
|
|
258
|
+
| `layout()` | Child layouts inside path are pre-rendered. Parent layouts are live. |
|
|
259
|
+
| `parallel()` | Parallel slots inside path are pre-rendered. |
|
|
260
|
+
| `middleware()` | Skipped during pre-render (no request). Runs at request time for loaders. |
|
|
261
|
+
| `loading()` | Ignored without Passthrough. Works for live fallback with Passthrough. |
|
|
262
|
+
| `intercept()` | Pre-rendered at build time. Intercept variant stored under `/i` key alongside main segments. At runtime, the correct variant is served based on `ctx.isIntercept`. `when` config conditions are skipped at build time (all intercepts are pre-rendered unconditionally). |
|
|
254
263
|
|
|
255
264
|
When Passthrough revalidation is enabled, remember that revalidation is
|
|
256
265
|
still partial: opting a child segment into revalidation does not
|
|
@@ -343,14 +352,31 @@ export const TocSidebar = Static(() => {
|
|
|
343
352
|
|
|
344
353
|
### Error behavior at build time
|
|
345
354
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
355
|
+
When a render throws a non-`Skip` error, it is **surfaced to the build** — never
|
|
356
|
+
baked into a frozen error page served as a 200 (issue #587). What happens next is
|
|
357
|
+
controlled by `prerender.onError` in your `rango()` options:
|
|
358
|
+
|
|
359
|
+
```ts
|
|
360
|
+
rango({ prerender: { onError: "warn" } }); // default is "fail"
|
|
361
|
+
```
|
|
352
362
|
|
|
353
|
-
|
|
363
|
+
| Handler outcome | `onError: "fail"` (default) | `onError: "warn"` |
|
|
364
|
+
| --------------------------- | -------------------------------------------- | -------------------------------- |
|
|
365
|
+
| JSX / `null` | Normal prerender entry, log OK | Normal prerender entry, log OK |
|
|
366
|
+
| `return ctx.passthrough()` | Skip entry, log PASS (Passthrough routes) | Skip entry, log PASS |
|
|
367
|
+
| `throw new Skip("reason")` | Skip entry, log SKIP, continue | Skip entry, log SKIP, continue |
|
|
368
|
+
| `throw new Error("reason")` | Log FAIL, stop ALL pre-rendering, fail build | Log WARN, skip the URL, continue |
|
|
369
|
+
|
|
370
|
+
With `"warn"` the errored entry is logged and left un-baked (never served as a baked
|
|
371
|
+
200 error page). `"warn"` is a build-unblock, not a runtime contract: the route falls
|
|
372
|
+
through to normal resolution — it may render live (its handler is still bundled) or
|
|
373
|
+
404 (once other baked entries trigger prerender handler eviction), so the outcome
|
|
374
|
+
depends on the rest of the build, and a skipped `Static()` handler's evicted code can
|
|
375
|
+
surface as an error. For DEFINED runtime behavior reach for `Passthrough()` (a live
|
|
376
|
+
fallback) or `throw new Skip()` (an intentional skip — works in the render fn, not
|
|
377
|
+
only `getParams()`); otherwise prefer the default `"fail"`.
|
|
378
|
+
|
|
379
|
+
Both `Skip` and hard errors propagate to the router's `onError` callback with phase
|
|
354
380
|
`"prerender"` or `"static"`.
|
|
355
381
|
|
|
356
382
|
### Build logs
|
|
@@ -370,9 +396,11 @@ The build produces per-URL timing logs:
|
|
|
370
396
|
[rango] Static render complete: 2 done, 1 skipped (120ms total)
|
|
371
397
|
```
|
|
372
398
|
|
|
373
|
-
A `FAIL` line is logged per-URL when a handler throws a non-Skip error
|
|
374
|
-
error is re-thrown immediately, so no
|
|
375
|
-
stops at the first failure.
|
|
399
|
+
A `FAIL` line is logged per-URL when a handler throws a non-Skip error (with the
|
|
400
|
+
default `prerender.onError: "fail"`). The error is re-thrown immediately, so no
|
|
401
|
+
summary line is printed — the build stops at the first failure. Under
|
|
402
|
+
`prerender.onError: "warn"` the same case logs a `WARN` line, skips that URL, and
|
|
403
|
+
the build continues.
|
|
376
404
|
|
|
377
405
|
### Dev mode behavior
|
|
378
406
|
|
|
@@ -588,12 +616,12 @@ At runtime, the cache-lookup middleware checks `ctx.isIntercept`:
|
|
|
588
616
|
(filtered by `namespace?.startsWith("intercept:")`) and sets up slots.
|
|
589
617
|
- **Direct navigation**: looks up `paramHash` (no suffix). Standard prerender path.
|
|
590
618
|
- **Intercept miss (no `/i` entry)**: falls through to the normal pipeline so
|
|
591
|
-
intercept-resolution middleware runs live. This handles `when
|
|
619
|
+
intercept-resolution middleware runs live. This handles `when` config conditions
|
|
592
620
|
that prevented pre-rendering.
|
|
593
621
|
|
|
594
|
-
The `when
|
|
622
|
+
The `when` config selector receives an `InterceptSelectorContext` with `from.pathname`
|
|
595
623
|
which is unknown at build time. All intercepts are pre-rendered unconditionally;
|
|
596
|
-
`when
|
|
624
|
+
`when` is evaluated at runtime by the intercept-resolution middleware.
|
|
597
625
|
|
|
598
626
|
### Example: Pre-rendered route with intercept
|
|
599
627
|
|
|
@@ -612,10 +640,13 @@ layout(ShopLayout, () => [
|
|
|
612
640
|
|
|
613
641
|
// Intercept detail from shop index into a modal.
|
|
614
642
|
// At build time, this is resolved and stored under the /i key.
|
|
615
|
-
intercept(
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
643
|
+
intercept(
|
|
644
|
+
"@modal",
|
|
645
|
+
".detail",
|
|
646
|
+
<ProductModal />,
|
|
647
|
+
{ when: ({ from }) => from.pathname === "/shop" },
|
|
648
|
+
() => [loader(ProductLoader)],
|
|
649
|
+
),
|
|
619
650
|
])
|
|
620
651
|
```
|
|
621
652
|
|
package/skills/rango/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rango
|
|
3
|
-
description: Overview of @rangojs/router and available skills
|
|
3
|
+
description: Overview of @rangojs/router and available skills. Use when unsure which skill to reach for, starting a new task in a Rango app, or asking "what can this router do".
|
|
4
4
|
argument-hint:
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -28,10 +28,10 @@ with the shape, then pick a primitive.
|
|
|
28
28
|
cache hit streams UI instantly while loaders resolve fresh alongside). Opt into
|
|
29
29
|
caching explicitly. See `/loader` → "Parallel and streaming".
|
|
30
30
|
- **One identity, one store** — loaders, handles, cached fns, and actions are all
|
|
31
|
-
`path#export`; all caches share one store. Entries expire by TTL/SWR
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
`path#export`; all caches share one store. Entries expire by TTL/SWR, and are
|
|
32
|
+
tagged via `cache({ tags })` or runtime `cacheTag(...tags)`; built-in stores
|
|
33
|
+
index by tag and invalidate via `updateTag(...tags)` (awaitable, read-your-own-writes)
|
|
34
|
+
or `revalidateTag(...tags)` (background, non-blocking).
|
|
35
35
|
- **Type-safe end to end** — route names, params, search schemas, loader return
|
|
36
36
|
types, context vars, and `href` / `reverse` are checked at compile time
|
|
37
37
|
(`/typesafety`).
|
|
@@ -59,36 +59,81 @@ appears, not up front.
|
|
|
59
59
|
To decide where something can live: **does it define a URL? structure, stays in
|
|
60
60
|
`urls()`. Does it modify a node? config, compose freely.**
|
|
61
61
|
|
|
62
|
+
## Passing data down the tree
|
|
63
|
+
|
|
64
|
+
Four ways to get per-request data to a segment below you, ordered safest-first.
|
|
65
|
+
Reach for the next rung only when the one above doesn't fit — the higher rungs
|
|
66
|
+
are immune to partial-revalidation staleness by construction.
|
|
67
|
+
|
|
68
|
+
1. **A loader** (`loader()` + `useLoader()`). Loaders resolve fresh on every
|
|
69
|
+
pass — full renders, action revalidations, cache hits. Nothing to keep in
|
|
70
|
+
sync. If the data can be a loader, make it a loader.
|
|
71
|
+
2. **Middleware `ctx.set()`**. Route middleware wraps every render pass,
|
|
72
|
+
including post-action revalidation and PE re-renders, so its variables are
|
|
73
|
+
never stale. Right for request-shaped context: auth, session, locale.
|
|
74
|
+
3. **Handler `ctx.set()` to its own children** —
|
|
75
|
+
`path(handler, ..., () => [layout(...)])`. Orphan layouts and their
|
|
76
|
+
parallels belong to the route entry: on an action the whole entry re-runs
|
|
77
|
+
together by default (handler-first preserved), so the data stays consistent
|
|
78
|
+
with zero configuration. Right for data the page must compute anyway —
|
|
79
|
+
e.g. pagination, where the handler's search decides how many pages the
|
|
80
|
+
layout chrome renders. One rule: if you narrow the entry's revalidation
|
|
81
|
+
with a predicate that can return a hard `false`, put the same contract on
|
|
82
|
+
the entry's children too — a hard `false` on one side of a
|
|
83
|
+
producer/consumer pair desyncs it.
|
|
84
|
+
4. **Cross-entry sharing** — an outer `layout()` entry feeding descendants.
|
|
85
|
+
Outer entries do NOT revalidate on actions by default (the revalidation
|
|
86
|
+
trace calls this `action:parent-chain-skip`), so this rung always requires
|
|
87
|
+
a shared revalidation contract: the same named `revalidate()` function on
|
|
88
|
+
the producer and every consumer. See `/layout` → "Revalidation Contracts".
|
|
89
|
+
Before writing one, check whether the producer can move down a rung.
|
|
90
|
+
|
|
91
|
+
The failure mode this ladder prevents: a consumer re-runs, its producer
|
|
92
|
+
doesn't, `ctx.get()` reads `undefined`, and fallback UI silently replaces good
|
|
93
|
+
UI after an action. Rungs 1–3 make that unrepresentable; rung 4 makes it a
|
|
94
|
+
stated, greppable contract.
|
|
95
|
+
|
|
62
96
|
## Pick a primitive
|
|
63
97
|
|
|
64
|
-
| I need to…
|
|
65
|
-
|
|
|
66
|
-
| render data fresh every request
|
|
67
|
-
| cache a rendered subtree
|
|
68
|
-
| cache one function/component's result
|
|
69
|
-
| cache a loader's data
|
|
70
|
-
| re-render a segment after an action
|
|
71
|
-
| mutate
|
|
72
|
-
| debug a slow request
|
|
73
|
-
| share config across routes
|
|
74
|
-
| compose a sub-app / module
|
|
75
|
-
| modal / soft navigation
|
|
76
|
-
| pre-render a route at build time
|
|
77
|
-
|
|
|
98
|
+
| I need to… | Use | Skill |
|
|
99
|
+
| --------------------------------------- | ---------------------------------- | ----------------------- |
|
|
100
|
+
| render data fresh every request | `loader()` + `useLoader()` | /loader |
|
|
101
|
+
| cache a rendered subtree | `cache()` on a segment | /caching |
|
|
102
|
+
| cache one function/component's result | `"use cache"` | /use-cache |
|
|
103
|
+
| cache a loader's data | `loader(L, () => [cache()])` | /loader, /caching |
|
|
104
|
+
| re-render a segment after an action | `revalidate()` | /loader |
|
|
105
|
+
| mutate | `"use server"` action | /server-actions |
|
|
106
|
+
| debug a slow request | `debugPerformance` / telemetry | /observability |
|
|
107
|
+
| share config across routes | factory returning a helper array | /composability |
|
|
108
|
+
| compose a sub-app / module | `include()` | /route |
|
|
109
|
+
| modal / soft navigation | `intercept()` | /intercept |
|
|
110
|
+
| pre-render a route at build time | `Prerender(...)` wrapper | /prerender |
|
|
111
|
+
| feed live loaders from a cached shell | replayed handle + `ctx.rendered()` | /shell-manifest |
|
|
112
|
+
| cache the HTML shell, keep loaders live | `ppr` path option | /ppr |
|
|
113
|
+
| stream SSE / upgrade a WebSocket | `path.stream()` / `path.any()` | /streams-and-websockets |
|
|
78
114
|
|
|
79
115
|
## Invariants
|
|
80
116
|
|
|
81
117
|
- `path()`/`include()` are always visible in `urls()`; config helpers are extractable.
|
|
82
118
|
- **Cache decides freshness; `revalidate()` decides client-update.** Orthogonal; compose.
|
|
83
119
|
- Loaders resolve fresh every request (even inside `cache()`) and never run twice/request.
|
|
120
|
+
- **The consumption-lane rule.** For every shared artifact (`cache()`,
|
|
121
|
+
`"use cache"`, the PPR shell): server-side handler consumption
|
|
122
|
+
(`await ctx.use(loader)`) yields a BAKED copy — identity reads
|
|
123
|
+
(`cookies()`/`headers()`) are permitted there and the capture-time value
|
|
124
|
+
freezes into the shared artifact (a documented footgun; see `/caching` →
|
|
125
|
+
"Cache purity & tainted objects"). Client-side consumption (`useLoader` in
|
|
126
|
+
a `"use client"` component) is the LIVE lane. DSL `loader()` segments
|
|
127
|
+
follow their lane machinery (live under renderable `loading()`, bake
|
|
128
|
+
otherwise). Pinned by semantic-matrix row PPR3.
|
|
84
129
|
- Inside `"use cache"`: `cookies()`/`headers()` and `ctx` side-effects
|
|
85
130
|
(`set`/`header`/`setTheme`/`onResponse`/`setLocationState`) throw; `ctx.use(Handle)`
|
|
86
131
|
is captured on miss and replayed on hit. (The non-cacheable read guard is a
|
|
87
132
|
separate `cache()`-boundary check — see the correctness bullet below.)
|
|
88
|
-
- One identity `path#export` (`functionId`/`$$id`/`actionId`); one store.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
133
|
+
- One identity `path#export` (`functionId`/`$$id`/`actionId`); one store. Freshness
|
|
134
|
+
is TTL/SWR expiry plus tag-based invalidation: tag via `cache({ tags })` /
|
|
135
|
+
`cacheTag(...tags)`, then `updateTag(...tags)` (awaitable) or `revalidateTag(...tags)`
|
|
136
|
+
(background). Built-in stores index by tag.
|
|
92
137
|
- `useLoader` / `useHandle` / `useFetchLoader` are client-only.
|
|
93
138
|
- Caches are correctness-first: persistent store keys are version-segmented (no
|
|
94
139
|
cross-deploy drift), the forward/back cache is mutation-aware, and
|
|
@@ -111,13 +156,14 @@ To decide where something can live: **does it define a URL? structure, stays in
|
|
|
111
156
|
Same words, different jobs — this is the most common source of the
|
|
112
157
|
`revalidate()`-is-caching misread.
|
|
113
158
|
|
|
114
|
-
| You may know
|
|
115
|
-
|
|
|
116
|
-
| Next.js `export const revalidate = N`
|
|
117
|
-
| Next.js `
|
|
118
|
-
| React Router / Remix `shouldRevalidate`
|
|
119
|
-
| HTTP `Cache-Control` / ISR
|
|
120
|
-
|
|
|
159
|
+
| You may know | Maps to Rango axis | Watch out |
|
|
160
|
+
| --------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
161
|
+
| Next.js `export const revalidate = N` | **Axis 1** (cache) | Same word, opposite meaning. Next's `revalidate` is time-based cache expiry; Rango's `revalidate()` is **axis 2**. Use `cache({ ttl })` for the Next behavior. |
|
|
162
|
+
| Next.js `revalidateTag` / `updateTag` | **Axis 1** (cache) | Cache busting by tag. Tag via `cache({ tags })` / `cacheTag(...tags)`; invalidate with `updateTag(...tags)` (awaitable, read-your-own-writes) or `revalidateTag(...tags)` (background, non-blocking). Built-in stores index by tag. No `revalidatePath` (path-based busting); use tags. |
|
|
163
|
+
| React Router / Remix `shouldRevalidate` | **Axis 2** | This is the correct mental model for Rango's `revalidate()`. |
|
|
164
|
+
| HTTP `Cache-Control` / ISR | **Axis 1** | Edge/document layer — see `/document-cache`. Separate from both `cache()` and `revalidate()`. |
|
|
165
|
+
| Next.js PPR (partial prerendering) | HTML shell layer | Same idea, different wiring: the opt-in `ppr` path option captures at runtime (no build-time default); holes are render-defined — `loading()` subtrees plus pending promises under a consumer's own `<Suspense>`. See `/ppr`. |
|
|
166
|
+
| Remix/RR `loader` | live data | Like Rango loaders, fresh per request — but Rango loaders run in parallel and stream (latency overlaps first paint), and can opt into caching on demand. |
|
|
121
167
|
|
|
122
168
|
See `/cache-guide` for the axis-1 decision guide, `/loader` and `/route` for
|
|
123
169
|
`revalidate()` (axis 2), and `/document-cache` for the edge layer.
|
|
@@ -154,6 +200,12 @@ returned, for outcome-conditional revalidation. The arg also exposes `actionId`
|
|
|
154
200
|
(raw `path#export`), `actionUrl`, `formData`, `method`, and `stale` (cross-tab
|
|
155
201
|
`_rsc_stale` signal). All are `undefined` on plain navigation (no action).
|
|
156
202
|
|
|
203
|
+
Two idioms, picked by what an _unrelated_ action should do. `ctx.isAction()`
|
|
204
|
+
returns a raw boolean, so combine it with `|| undefined` to **defer** ("mine,
|
|
205
|
+
else let the default decide": `ctx.isAction(CartActions) || undefined`) or leave
|
|
206
|
+
it bare to **suppress** ("mine only": `ctx.isAction(CartActions)`). Prefer the
|
|
207
|
+
defer form unless a sibling segment must own the unrelated-action decision.
|
|
208
|
+
|
|
157
209
|
```ts
|
|
158
210
|
// re-render only when checkout actually succeeded; defer otherwise
|
|
159
211
|
revalidate((ctx) => (ctx.isAction(checkout) && ctx.actionResult?.ok) || undefined),
|
|
@@ -179,6 +231,12 @@ resolve `dist/` outside `./vite`, and it may lag `src/`.
|
|
|
179
231
|
|
|
180
232
|
Grouped by concern — read when you need to…
|
|
181
233
|
|
|
234
|
+
**Positioning & evaluation**:
|
|
235
|
+
|
|
236
|
+
| Skill | Description |
|
|
237
|
+
| ------------- | ------------------------------------------------------------ |
|
|
238
|
+
| `/comparison` | Compare Rango with Next.js, TanStack Start, and Waku fairly. |
|
|
239
|
+
|
|
182
240
|
**Structure & routing** — shape URLs, layouts, navigation, and request processing:
|
|
183
241
|
|
|
184
242
|
| Skill | Description |
|
|
@@ -192,6 +250,7 @@ Grouped by concern — read when you need to…
|
|
|
192
250
|
| `/host-router` | Multi-app host routing with domain/subdomain patterns |
|
|
193
251
|
| `/links` | URL generation: ctx.reverse, href, useHref, useMount, scopedReverse |
|
|
194
252
|
| `/response-routes` | JSON/text/HTML/XML/stream endpoints with `path.json()`, `path.text()` |
|
|
253
|
+
| `/api-client` | Typed client for consuming your own response-route JSON APIs (recipe) |
|
|
195
254
|
| `/mime-routes` | Content negotiation — same URL, different response types via Accept header |
|
|
196
255
|
| `/streams-and-websockets` | SSE via `path.stream` and WebSocket upgrades via `path.any` |
|
|
197
256
|
| `/handler-use` | Attach default loaders/middleware to a handler via `handler.use` |
|
|
@@ -199,28 +258,33 @@ Grouped by concern — read when you need to…
|
|
|
199
258
|
|
|
200
259
|
**Data & caching** — fetch, mutate, and cache:
|
|
201
260
|
|
|
202
|
-
| Skill | Description
|
|
203
|
-
| ----------------- |
|
|
204
|
-
| `/loader` | Data loaders with `createLoader()` and `revalidate()`
|
|
205
|
-
| `/server-actions` | Mutations with `"use server"`, useActionState, validation, revalidation
|
|
206
|
-
| `/caching` | Segment caching with memory or KV stores
|
|
207
|
-
| `/use-cache` | Function-level caching with `"use cache"` directive
|
|
208
|
-
| `/cache-guide` | When to use `cache()` vs `"use cache"` — differences and decision guide
|
|
209
|
-
| `/document-cache` | Edge caching with Cache-Control headers
|
|
210
|
-
| `/
|
|
261
|
+
| Skill | Description |
|
|
262
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
263
|
+
| `/loader` | Data loaders with `createLoader()` and `revalidate()` |
|
|
264
|
+
| `/server-actions` | Mutations with `"use server"`, useActionState, validation, revalidation |
|
|
265
|
+
| `/caching` | Segment caching with memory or KV stores |
|
|
266
|
+
| `/use-cache` | Function-level caching with `"use cache"` directive |
|
|
267
|
+
| `/cache-guide` | When to use `cache()` vs `"use cache"` — differences and decision guide |
|
|
268
|
+
| `/document-cache` | Edge caching with Cache-Control headers |
|
|
269
|
+
| `/ppr` | PPR shell caching: cached shell served instantly, live holes resumed — a hole is a `loading()` subtree OR a pending promise under `<Suspense>` (no loader needed) |
|
|
270
|
+
| `/prerender` | Pre-render route segments at build time (Passthrough live fallback) |
|
|
271
|
+
| `/shell-manifest` | Replayed handles as cache metadata read by live loaders (frozen shell, batched live holes) |
|
|
211
272
|
|
|
212
273
|
**Client & presentation** — build the client-side UX:
|
|
213
274
|
|
|
214
|
-
| Skill | Description
|
|
215
|
-
| ------------------- |
|
|
216
|
-
| `/hooks` | Client-side React hooks
|
|
217
|
-
| `/theme` | Light/dark mode with FOUC prevention
|
|
218
|
-
| `/i18n` | Locale routing with `:locale?`, resolution chains, react-intl integration
|
|
219
|
-
| `/fonts` | Load web fonts with preload hints
|
|
220
|
-
| `/
|
|
221
|
-
| `/
|
|
222
|
-
| `/
|
|
223
|
-
| `/
|
|
275
|
+
| Skill | Description |
|
|
276
|
+
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
277
|
+
| `/hooks` | Client-side React hooks |
|
|
278
|
+
| `/theme` | Light/dark mode with FOUC prevention |
|
|
279
|
+
| `/i18n` | Locale routing with `:locale?`, resolution chains, react-intl integration |
|
|
280
|
+
| `/fonts` | Load web fonts with preload hints |
|
|
281
|
+
| `/css` | Import CSS in the Document `<head>` (`?url` + managed `precedence` links) |
|
|
282
|
+
| `/scripts` | Inject third-party scripts (GTM/analytics) into head/body via the `Script` handle; nonce auto-applied to document-rendered scripts |
|
|
283
|
+
| `/tailwind` | Set up Tailwind CSS v4 with `?url` imports |
|
|
284
|
+
| `/view-transitions` | React View Transitions on layouts, routes, and parallel slots |
|
|
285
|
+
| `/defer-hydration` | Full body HTML in the PPR shell + hydration off the critical path (gated Suspense boundary, content-as-fallback) |
|
|
286
|
+
| `/breadcrumbs` | Built-in Breadcrumbs handle for breadcrumb navigation |
|
|
287
|
+
| `/react-compiler` | Enable React Compiler (opt-in) the vite-rsc way; client-only scope |
|
|
224
288
|
|
|
225
289
|
**Observability & production health**:
|
|
226
290
|
|
|
@@ -230,6 +294,12 @@ Grouped by concern — read when you need to…
|
|
|
230
294
|
| `/bundle-analysis` | Audit your app's production bundle for server leaks and oversized chunks |
|
|
231
295
|
| `/debug-manifest` | Inspect route manifest structure |
|
|
232
296
|
|
|
297
|
+
**Deployment**:
|
|
298
|
+
|
|
299
|
+
| Skill | Description |
|
|
300
|
+
| --------- | ----------------------------------------------------------------------------------------- |
|
|
301
|
+
| `/vercel` | Deploy to Vercel Functions (`preset: "vercel"`), Runtime Cache, and `createVercelTracing` |
|
|
302
|
+
|
|
233
303
|
**Testing**:
|
|
234
304
|
|
|
235
305
|
| Skill | Description |
|
|
@@ -310,7 +380,11 @@ dotfiles, and existing `.gen.` files.
|
|
|
310
380
|
### Recursive includes
|
|
311
381
|
|
|
312
382
|
The generator follows `include()` calls across files, resolving imports to build
|
|
313
|
-
the full route tree.
|
|
383
|
+
the full route tree. It resolves both the eager form `include("/x", patterns)`
|
|
384
|
+
and the code-split async form `include("/x", () => import("./x"))` — for the
|
|
385
|
+
latter it walks the imported module's `export default urls(...)`, including any
|
|
386
|
+
nested `include()`s inside it — so a code-split route group is still fully typed
|
|
387
|
+
(see `/composability`). Circular includes are detected and warned about.
|
|
314
388
|
|
|
315
389
|
### First-wins deduplication
|
|
316
390
|
|