@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327
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 +301 -797
- package/dist/bin/rango.js +603 -145
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3750 -1160
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +96 -24
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- 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 +110 -4
- 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 +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +12 -10
- package/skills/hooks/SKILL.md +73 -691
- 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 +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +75 -19
- package/skills/layout/SKILL.md +40 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +25 -13
- package/skills/migrate-nextjs/SKILL.md +205 -20
- package/skills/migrate-react-router/SKILL.md +59 -670
- 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 +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +40 -10
- package/skills/ppr/SKILL.md +616 -0
- package/skills/prerender/SKILL.md +72 -60
- package/skills/rango/SKILL.md +318 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +117 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- 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 -626
- 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 +74 -15
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +0 -65
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- 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 +94 -25
- package/src/browser/navigation-client.ts +144 -79
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +183 -144
- package/src/browser/prefetch/cache.ts +242 -77
- package/src/browser/prefetch/fetch.ts +325 -69
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +58 -20
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +17 -14
- 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 +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +25 -3
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +145 -28
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +203 -154
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -21
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +456 -62
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +128 -51
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- 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 +421 -58
- package/src/cache/cache-scope.ts +187 -96
- 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 +2202 -372
- 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 +180 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1127 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +33 -61
- 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 +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +67 -37
- 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 +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +97 -12
- package/src/index.ts +98 -14
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- 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 +78 -10
- 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 +62 -0
- package/src/reverse.ts +65 -39
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +304 -309
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +87 -59
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +12 -1
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +19 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +73 -25
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +27 -42
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +82 -59
- package/src/router/loader-resolution.ts +167 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +80 -55
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +159 -285
- package/src/router/match-middleware/cache-store.ts +64 -52
- 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 +69 -79
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- 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 +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +112 -67
- package/src/router/preview-match.ts +6 -2
- package/src/router/request-classification.ts +50 -69
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +115 -36
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +131 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +139 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +251 -0
- package/src/router/segment-resolution/revalidation.ts +272 -320
- 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 +56 -0
- 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 +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +157 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +291 -217
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- 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 +39 -25
- package/src/rsc/progressive-enhancement.ts +124 -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 +99 -189
- package/src/rsc/rsc-rendering.ts +421 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +282 -116
- package/src/rsc/shell-capture.ts +1158 -0
- package/src/rsc/shell-serve.ts +150 -0
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +53 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +350 -149
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +208 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +395 -176
- package/src/ssr/index.tsx +458 -178
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- 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 +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- 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 +54 -41
- package/src/types/handler-context.ts +110 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +11 -9
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +19 -64
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +63 -17
- package/src/urls/path-helper.ts +22 -106
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +8 -7
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +96 -68
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +45 -1
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +4 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +210 -10
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +88 -55
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +505 -486
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +236 -138
- package/src/vite/router-discovery.ts +927 -136
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +71 -43
- package/src/vite/utils/shared-utils.ts +142 -43
- package/src/browser/action-response-classifier.ts +0 -99
- 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: router-setup
|
|
3
|
-
description: Create and configure the RSC router with createRouter
|
|
3
|
+
description: Create and configure the RSC router with createRouter. Use when bootstrapping a new Rango app, or configuring top-level router options like base path, cache store, or environment.
|
|
4
4
|
argument-hint: [option]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -60,8 +60,10 @@ urls(
|
|
|
60
60
|
cache, // Configure caching
|
|
61
61
|
middleware, // Add middleware
|
|
62
62
|
revalidate, // Control revalidation
|
|
63
|
-
intercept, // Intercept routes for modals
|
|
64
|
-
|
|
63
|
+
intercept, // Intercept routes for modals (conditional via intercept(..., { when }))
|
|
64
|
+
errorBoundary, // Add an error boundary
|
|
65
|
+
notFoundBoundary, // Add a not-found boundary
|
|
66
|
+
transition, // Configure view transitions
|
|
65
67
|
}) => [
|
|
66
68
|
// Route definitions here
|
|
67
69
|
],
|
|
@@ -71,7 +73,7 @@ urls(
|
|
|
71
73
|
## Router Options
|
|
72
74
|
|
|
73
75
|
```typescript
|
|
74
|
-
interface
|
|
76
|
+
interface RangoOptions<TEnv> {
|
|
75
77
|
// URL patterns from urls() function
|
|
76
78
|
urls: UrlPatterns;
|
|
77
79
|
|
|
@@ -396,6 +398,18 @@ export const urlpatterns = urls(({ path, include }) => [
|
|
|
396
398
|
]);
|
|
397
399
|
```
|
|
398
400
|
|
|
401
|
+
`include()` also accepts an async provider to code-split that group into its own
|
|
402
|
+
chunk, imported on the first request reaching the prefix instead of at startup:
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
// urls/shop.tsx: `export default shopPatterns`
|
|
406
|
+
include("/shop", () => import("./urls/shop"), { name: "shop" }),
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Build-time discovery still `await`s the provider, so route types, `href()`, and
|
|
410
|
+
prerender see every route in the split group. Reach for it when a group is a
|
|
411
|
+
large, independently-loadable unit — see `/composability`.
|
|
412
|
+
|
|
399
413
|
## Environment Types
|
|
400
414
|
|
|
401
415
|
```typescript
|
|
@@ -405,7 +419,7 @@ interface AppBindings {
|
|
|
405
419
|
KV: KVNamespace;
|
|
406
420
|
}
|
|
407
421
|
|
|
408
|
-
// Variables declared via
|
|
422
|
+
// Variables declared via global namespace augmentation
|
|
409
423
|
interface AppVariables {
|
|
410
424
|
user?: { id: string; name: string };
|
|
411
425
|
}
|
|
@@ -417,7 +431,7 @@ const router = createRouter<AppBindings>({
|
|
|
417
431
|
|
|
418
432
|
// Register types globally for implicit typing
|
|
419
433
|
declare global {
|
|
420
|
-
namespace
|
|
434
|
+
namespace Rango {
|
|
421
435
|
interface Env extends AppBindings {}
|
|
422
436
|
interface Vars extends AppVariables {}
|
|
423
437
|
}
|
|
@@ -469,14 +483,35 @@ const router = createRouter({
|
|
|
469
483
|
```
|
|
470
484
|
|
|
471
485
|
```typescript
|
|
472
|
-
// OpenTelemetry for production
|
|
473
|
-
|
|
486
|
+
// OpenTelemetry for production: phase spans via the tracing slot,
|
|
487
|
+
// discrete-fact spans via the telemetry sink.
|
|
488
|
+
import {
|
|
489
|
+
createRouter,
|
|
490
|
+
createOTelTracing,
|
|
491
|
+
createOTelSink,
|
|
492
|
+
} from "@rangojs/router";
|
|
474
493
|
import { trace } from "@opentelemetry/api";
|
|
475
494
|
|
|
495
|
+
const tracer = trace.getTracer("my-app");
|
|
496
|
+
|
|
497
|
+
const router = createRouter({
|
|
498
|
+
document: Document,
|
|
499
|
+
urls: urlpatterns,
|
|
500
|
+
tracing: createOTelTracing(tracer),
|
|
501
|
+
telemetry: createOTelSink(tracer),
|
|
502
|
+
});
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
// On Cloudflare Workers, swap the tracing factory for native custom spans
|
|
507
|
+
// (no @opentelemetry/api dependency); the telemetry slot is unchanged.
|
|
508
|
+
// On Vercel (Node runtime) use createVercelTracing() from @rangojs/router/vercel.
|
|
509
|
+
import { createCloudflareTracing } from "@rangojs/router/cloudflare";
|
|
510
|
+
|
|
476
511
|
const router = createRouter({
|
|
477
512
|
document: Document,
|
|
478
513
|
urls: urlpatterns,
|
|
479
|
-
|
|
514
|
+
tracing: createCloudflareTracing(), // { spans: { ssr: false } } to toggle phases
|
|
480
515
|
});
|
|
481
516
|
```
|
|
482
517
|
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scripts
|
|
3
|
+
description: Inject third-party scripts (GTM, analytics, widgets) into the document head/body via the Script handle. Use when adding Google Tag Manager, an analytics snippet, or a third-party widget script to the page.
|
|
4
|
+
argument-hint: "[vendor]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Scripts
|
|
8
|
+
|
|
9
|
+
Inject `<script>` tags into the document the idiomatic Rango way: push a config
|
|
10
|
+
from a **server** route/layout handler with `ctx.use(Script)(config)`, and render
|
|
11
|
+
them with the built-in **`<Scripts />`** component (the `Meta` / `<MetaTags>`
|
|
12
|
+
pair, but for scripts). The request CSP **nonce is applied automatically to
|
|
13
|
+
document-rendered scripts** — you never read or pass it. (The one exception is an
|
|
14
|
+
async script first encountered on a soft navigation; see the nonce caveat under
|
|
15
|
+
"Execution contract".)
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
`<Scripts />` is a client component; place it in your Document (which is
|
|
20
|
+
`"use client"`). The default Document already includes both sites; a custom one
|
|
21
|
+
adds them next to `<MetaTags />`:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
// document.tsx ("use client")
|
|
25
|
+
import { MetaTags, Scripts } from "@rangojs/router/client";
|
|
26
|
+
|
|
27
|
+
export function Document({ children }) {
|
|
28
|
+
return (
|
|
29
|
+
<html lang="en" suppressHydrationWarning>
|
|
30
|
+
<head>
|
|
31
|
+
<MetaTags />
|
|
32
|
+
<Scripts /> {/* renders position: "head" scripts (the default) */}
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<Scripts position="body" /> {/* renders position: "body" scripts */}
|
|
36
|
+
{children}
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Push from a handler
|
|
44
|
+
|
|
45
|
+
`ScriptConfig` is a discriminated union — exactly one of three shapes, so invalid
|
|
46
|
+
combinations are compile errors:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { Script } from "@rangojs/router";
|
|
50
|
+
|
|
51
|
+
// 1. External ASYNC — a React resource. Loads once when first encountered,
|
|
52
|
+
// including after a soft navigation, deduped by src. The fire-and-forget case.
|
|
53
|
+
ctx.use(Script)({ id: "stripe", src: "https://js.stripe.com/v3", async: true });
|
|
54
|
+
|
|
55
|
+
// 2. External ORDERED — in-place, optional `defer`. Document-load (see below).
|
|
56
|
+
ctx.use(Script)({
|
|
57
|
+
id: "plausible",
|
|
58
|
+
src: "https://plausible.io/js/script.js",
|
|
59
|
+
defer: true,
|
|
60
|
+
attributes: { "data-domain": "example.com" },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// 3. INLINE — `id` REQUIRED, raw JS body (escaped against </script> by <Scripts>).
|
|
64
|
+
// For GTM/GA4/Segment let the body self-inject its loader (see below).
|
|
65
|
+
ctx.use(Script)({ id: "gtm", children: gtmBootstrap("GTM-XXXX") });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Shape | Required | Optional | Forbidden |
|
|
69
|
+
| ---------------- | -------------------- | ----------------------------------------------- | ----------------------- |
|
|
70
|
+
| Inline | `id`, `children` | `position`, `type`, `attributes` | `src`, `async`, `defer` |
|
|
71
|
+
| External async | `src`, `async: true` | `id`, `position`, `type`, `attributes` | `children`, `defer` |
|
|
72
|
+
| External ordered | `src` | `defer`, `id`, `position`, `type`, `attributes` | `children`, `async` |
|
|
73
|
+
|
|
74
|
+
- `id` — dedup key (last-push-wins), and rendered as the script's DOM `id` (for
|
|
75
|
+
vendors that target `<script id="…">`). Required for inline (React never dedups
|
|
76
|
+
inline scripts); for ordered external it falls back to `src`. Async externals
|
|
77
|
+
dedup by `src` (matching React), so there `id` is the DOM id only.
|
|
78
|
+
- `position` — `"head"` (default) or `"body"`. An async script is hoisted to
|
|
79
|
+
`<head>` by React regardless.
|
|
80
|
+
- `type` — free string: `"module"`, `"application/ld+json"`, `"text/partytown"`, …
|
|
81
|
+
- `attributes` — React-cased (`crossOrigin`, not `crossorigin`) and React-typed
|
|
82
|
+
(`data-*`, `integrity`, `referrerPolicy`, …). Excluded: the fields the handle
|
|
83
|
+
manages (`id`/`src`/`async`/`defer`/`type`/`children`/`nonce`) and all `on*`
|
|
84
|
+
handlers (`onLoad`/`onError`/… — a config is serialized to the client, so a
|
|
85
|
+
function can't survive; use a `"use client"` component for callbacks).
|
|
86
|
+
|
|
87
|
+
## Execution contract (read this)
|
|
88
|
+
|
|
89
|
+
React makes a `<script>` it mounts on the client INERT (it creates the element via
|
|
90
|
+
innerHTML, which the HTML spec never executes). So:
|
|
91
|
+
|
|
92
|
+
| Script | Runs on hard load | Runs on soft (`<Link>`) navigation |
|
|
93
|
+
| -------------------------------- | ------------------------------ | ----------------------------------------------------- |
|
|
94
|
+
| Inline (`children`) | Yes (it's in the initial HTML) | **No** — it is document-load only |
|
|
95
|
+
| External ordered (`defer`/plain) | Yes | **No** — document-load only |
|
|
96
|
+
| External `async` | Yes | **Yes** — React loads the resource on first encounter |
|
|
97
|
+
|
|
98
|
+
`<Scripts>` enforces this honestly: after hydration it **freezes** the inline +
|
|
99
|
+
ordered set to what was in the initial HTML, so a navigation never inserts an
|
|
100
|
+
inert (silently dead) `<script>`. Async configs stay reactive. Reusing an `id`
|
|
101
|
+
shapes the INITIAL document output (last-push-wins) — it does not re-run a script
|
|
102
|
+
during navigation.
|
|
103
|
+
|
|
104
|
+
**Nonce caveat for soft-nav async.** The "nonce is applied automatically" claim
|
|
105
|
+
holds for DOCUMENT-RENDERED scripts (they carry the nonce in the SSR HTML). An
|
|
106
|
+
async script first encountered on a soft navigation is injected by React on the
|
|
107
|
+
client, where `useNonce()` is `undefined` by design (the router does not serialize
|
|
108
|
+
the nonce to the client — that would weaken CSP), so it has no nonce attribute. It
|
|
109
|
+
still loads under `'strict-dynamic'` (React's nonced runtime injects it, so the
|
|
110
|
+
trust propagates) — which is the recommended policy — or if your `script-src`
|
|
111
|
+
allows the host. A nonce-only policy without `'strict-dynamic'` would block it.
|
|
112
|
+
|
|
113
|
+
**Per-navigation behavior belongs in a client component or hook**, not in a
|
|
114
|
+
re-pushed inline script. The GTM demo does exactly this: a root-layout `Script`
|
|
115
|
+
bootstrap fires the first page_view on document load, and a `"use client"`
|
|
116
|
+
`<GtmPageViews>` component fires a page_view on every subsequent soft navigation.
|
|
117
|
+
|
|
118
|
+
## The inline-self-inject rule (GTM/GA4/Segment)
|
|
119
|
+
|
|
120
|
+
If an inline bootstrap must run **before** an external loader, do NOT push the
|
|
121
|
+
loader as a separate `{ src, async }` config: React 19 hoists a declarative
|
|
122
|
+
`<script async src>` to the **top** of `<head>`, above your inline bootstrap, so
|
|
123
|
+
the loader could run before the bootstrap. Instead let the bootstrap inject its
|
|
124
|
+
own loader (Google's snippet does exactly this):
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
function gtmBootstrap(id: string): string {
|
|
128
|
+
return [
|
|
129
|
+
"window.dataLayer=window.dataLayer||[];",
|
|
130
|
+
'window.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"});',
|
|
131
|
+
`(function(d,s,i){var j=d.createElement(s);j.async=true;j.src="https://www.googletagmanager.com/gtm.js?id="+encodeURIComponent(i);var f=d.getElementsByTagName(s)[0];f.parentNode.insertBefore(j,f);})(document,"script",${JSON.stringify(id)});`,
|
|
132
|
+
].join("");
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Under a `'strict-dynamic'` CSP the nonced inline script vouches for the loader it
|
|
137
|
+
creates, so the injected loader needs no nonce of its own.
|
|
138
|
+
|
|
139
|
+
### Per-route tagging on the first render
|
|
140
|
+
|
|
141
|
+
A route can **override** a layout's bootstrap by reusing the `id`, baking
|
|
142
|
+
per-route data into the FIRST (hard-load) page_view server-side — the Script
|
|
143
|
+
handle is collected after handlers run (parent → child, last-wins):
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// root layout: generic bootstrap
|
|
147
|
+
ctx.use(Script)({ id: "gtm", children: gtmBootstrap("GTM-XXXX") });
|
|
148
|
+
// a route: same id, with content_group baked in
|
|
149
|
+
ctx.use(Script)({
|
|
150
|
+
id: "gtm",
|
|
151
|
+
children: gtmBootstrapWith({ content_group: "blog" }),
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## CSP
|
|
156
|
+
|
|
157
|
+
The nonce is automatic for document-rendered scripts. Include `'strict-dynamic'`
|
|
158
|
+
in `script-src` (recommended): besides letting a nonced loader vouch for the
|
|
159
|
+
scripts it injects, it also covers the one nonce-less case — an async script first
|
|
160
|
+
loaded on a soft navigation is injected client-side without a nonce (see the
|
|
161
|
+
caveat above), and `'strict-dynamic'` trusts it via React's nonced runtime.
|
|
162
|
+
Otherwise allow the vendor hosts. For GTM/GA4 (Google's wildcards): `script-src
|
|
163
|
+
'self' 'nonce-…' 'strict-dynamic' https://*.googletagmanager.com`, plus `img-src`
|
|
164
|
+
/ `connect-src` for `*.google-analytics.com` / `*.analytics.google.com`, and
|
|
165
|
+
`frame-src https://*.googletagmanager.com` for the GTM `<noscript>` iframe. See
|
|
166
|
+
[Google's CSP guide](https://developers.google.com/tag-platform/security/guides/csp).
|
|
167
|
+
|
|
168
|
+
## Not covered (do it yourself)
|
|
169
|
+
|
|
170
|
+
- **`onLoad` / `onReady` / `onError`** — callbacks can't cross the server handle
|
|
171
|
+
boundary. Render your own `"use client"` component with a load listener keyed
|
|
172
|
+
off the script id.
|
|
173
|
+
- **`<noscript>` fallbacks** (e.g. the GTM body iframe) — not a `<script>`;
|
|
174
|
+
render it directly in your Document `<body>`.
|
|
175
|
+
- **Partytown / web-worker offloading** — push the worker config with
|
|
176
|
+
`type: "text/partytown"` and wire Partytown's own nonce config manually.
|
|
177
|
+
|
|
178
|
+
A full GTM + GA4-style integration (page_view on first render + soft nav, nonce,
|
|
179
|
+
ecommerce events) lives in `tests/vite-rsc-demo`.
|