vinext 0.0.49 → 0.0.50
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/dist/build/client-build-config.js.map +1 -1
- package/dist/build/google-fonts/build-url.js.map +1 -1
- package/dist/build/google-fonts/get-axes.js.map +1 -1
- package/dist/build/google-fonts/sort-variants.js.map +1 -1
- package/dist/build/google-fonts/validate.js.map +1 -1
- package/dist/build/layout-classification.js.map +1 -1
- package/dist/build/nitro-route-rules.js.map +1 -1
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +17 -1
- package/dist/build/prerender.js +77 -16
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.js.map +1 -1
- package/dist/build/route-classification-injector.js.map +1 -1
- package/dist/build/route-classification-manifest.js.map +1 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/server-manifest.js.map +1 -1
- package/dist/build/ssr-manifest.js.map +1 -1
- package/dist/build/standalone.js.map +1 -1
- package/dist/build/static-export.js.map +1 -1
- package/dist/check.js +1 -1
- package/dist/check.js.map +1 -1
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +8 -4
- package/dist/cli.js.map +1 -1
- package/dist/client/instrumentation-client-state.js.map +1 -1
- package/dist/client/validate-module-path.js.map +1 -1
- package/dist/client/vinext-next-data.d.ts +5 -1
- package/dist/client/window-next.d.ts +149 -0
- package/dist/client/window-next.js +48 -0
- package/dist/client/window-next.js.map +1 -0
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.js +2 -1
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.d.ts +3 -1
- package/dist/config/config-matchers.js +5 -4
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +13 -2
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +13 -5
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +3 -1
- package/dist/entries/app-browser-entry.js +11 -2
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.js +11 -0
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.js +4 -0
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/app-ssr-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-entry-helpers.js.map +1 -1
- package/dist/entries/pages-server-entry.js +15 -0
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +76 -18
- package/dist/index.js.map +1 -1
- package/dist/init.js.map +1 -1
- package/dist/plugins/async-hooks-stub.js.map +1 -1
- package/dist/plugins/client-reference-dedup.js.map +1 -1
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/instrumentation-client.js.map +1 -1
- package/dist/plugins/og-assets.js.map +1 -1
- package/dist/plugins/optimize-imports.js.map +1 -1
- package/dist/plugins/postcss.js.map +1 -1
- package/dist/plugins/rsc-client-reference-loaders.d.ts +7 -0
- package/dist/plugins/rsc-client-reference-loaders.js +48 -0
- package/dist/plugins/rsc-client-reference-loaders.js.map +1 -0
- package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
- package/dist/plugins/server-externals-manifest.js.map +1 -1
- package/dist/plugins/strip-server-exports.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +48 -5
- package/dist/routing/app-route-graph.js +159 -15
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-matching.js.map +1 -1
- package/dist/routing/route-pattern.js.map +1 -1
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/route-validation.js.map +1 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +19 -0
- package/dist/server/app-browser-action-result.js +18 -0
- package/dist/server/app-browser-action-result.js.map +1 -0
- package/dist/server/app-browser-entry.js +91 -48
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-error.js.map +1 -1
- package/dist/server/app-browser-hydration.d.ts +19 -0
- package/dist/server/app-browser-hydration.js +22 -0
- package/dist/server/app-browser-hydration.js.map +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +6 -3
- package/dist/server/app-browser-navigation-controller.js +67 -19
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-state.d.ts +17 -17
- package/dist/server/app-browser-state.js +122 -36
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +4 -0
- package/dist/server/app-browser-stream.js +24 -2
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +34 -19
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-client-reference-preloader.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +17 -1
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-hook-warning-suppression.js.map +1 -1
- package/dist/server/app-middleware.d.ts +1 -1
- package/dist/server/app-middleware.js +4 -9
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-mounted-slots-header.js.map +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +14 -13
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +1 -0
- package/dist/server/app-page-boundary.js +7 -5
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +10 -3
- package/dist/server/app-page-cache.js +42 -23
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +6 -1
- package/dist/server/app-page-dispatch.js +21 -7
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +3 -1
- package/dist/server/app-page-element-builder.js +6 -2
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.js +4 -0
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-method.js.map +1 -1
- package/dist/server/app-page-params.js.map +1 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render.d.ts +7 -1
- package/dist/server/app-page-render.js +11 -4
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +2 -0
- package/dist/server/app-page-response.js +15 -5
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +6 -2
- package/dist/server/app-page-route-wiring.js +50 -49
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-segment-state.d.ts +10 -0
- package/dist/server/app-page-segment-state.js +87 -0
- package/dist/server/app-page-segment-state.js.map +1 -0
- package/dist/server/app-page-stream.d.ts +7 -2
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-post-middleware-context.js.map +1 -1
- package/dist/server/app-prerender-endpoints.js.map +1 -1
- package/dist/server/app-prerender-static-params.js.map +1 -1
- package/dist/server/app-render-dependency.js.map +1 -1
- package/dist/server/app-request-context.js.map +1 -1
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-policy.js +1 -0
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.js +4 -3
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-router-entry.js +6 -2
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +5 -2
- package/dist/server/app-rsc-cache-busting.js +40 -19
- package/dist/server/app-rsc-cache-busting.js.map +1 -1
- package/dist/server/app-rsc-error-handler.js.map +1 -1
- package/dist/server/app-rsc-errors.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +10 -1
- package/dist/server/app-rsc-handler.js +51 -17
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-render-mode.d.ts +11 -0
- package/dist/server/app-rsc-render-mode.js +21 -0
- package/dist/server/app-rsc-render-mode.js.map +1 -0
- package/dist/server/app-rsc-request-normalization.d.ts +4 -1
- package/dist/server/app-rsc-request-normalization.js +7 -2
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-rsc-response-finalizer.d.ts +2 -1
- package/dist/server/app-rsc-response-finalizer.js +6 -1
- package/dist/server/app-rsc-response-finalizer.js.map +1 -1
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-segment-config.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +16 -2
- package/dist/server/app-server-action-execution.js +79 -23
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +10 -4
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/app-static-generation.js.map +1 -1
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-control.js +1 -0
- package/dist/server/cache-control.js.map +1 -1
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/csp.js.map +1 -1
- package/dist/server/dev-error-overlay-store.js.map +1 -1
- package/dist/server/dev-error-overlay.js +5 -0
- package/dist/server/dev-error-overlay.js.map +1 -1
- package/dist/server/dev-module-runner.js.map +1 -1
- package/dist/server/dev-origin-check.js.map +1 -1
- package/dist/server/dev-route-files.js.map +1 -1
- package/dist/server/dev-server.js +8 -5
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/file-based-metadata.js.map +1 -1
- package/dist/server/headers.d.ts +79 -0
- package/dist/server/headers.js +101 -0
- package/dist/server/headers.js.map +1 -0
- package/dist/server/html.js.map +1 -1
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/image-optimization.d.ts +11 -1
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/implicit-tags.js +2 -1
- package/dist/server/implicit-tags.js.map +1 -1
- package/dist/server/instrumentation-runtime.js.map +1 -1
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +10 -1
- package/dist/server/isr-cache.js +12 -3
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-build-data.js.map +1 -1
- package/dist/server/metadata-route-response.js.map +1 -1
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-matcher.js.map +1 -1
- package/dist/server/middleware-request-headers.d.ts +4 -1
- package/dist/server/middleware-request-headers.js +15 -8
- package/dist/server/middleware-request-headers.js.map +1 -1
- package/dist/server/middleware-response-headers.d.ts +2 -1
- package/dist/server/middleware-response-headers.js +1 -1
- package/dist/server/middleware-response-headers.js.map +1 -1
- package/dist/server/middleware-runtime.d.ts +1 -0
- package/dist/server/middleware-runtime.js +6 -3
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +119 -0
- package/dist/server/navigation-planner.js +171 -0
- package/dist/server/navigation-planner.js.map +1 -0
- package/dist/server/navigation-trace.d.ts +12 -2
- package/dist/server/navigation-trace.js +13 -1
- package/dist/server/navigation-trace.js.map +1 -1
- package/dist/server/next-error-digest.d.ts +3 -2
- package/dist/server/next-error-digest.js +4 -2
- package/dist/server/next-error-digest.js.map +1 -1
- package/dist/server/normalize-path.js.map +1 -1
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-media-type.js.map +1 -1
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-data.js +5 -2
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.js +3 -2
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prerender-work-unit-setup.js +1 -1
- package/dist/server/prerender-work-unit-setup.js.map +1 -1
- package/dist/server/prod-server.js +35 -13
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-log.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +1 -13
- package/dist/server/request-pipeline.js +3 -25
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/rsc-stream-hints.js.map +1 -1
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.js +3 -3
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/socket-error-backstop.js.map +1 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/server/worker-utils.d.ts +0 -7
- package/dist/server/worker-utils.js +3 -2
- package/dist/server/worker-utils.js.map +1 -1
- package/dist/shims/amp.js.map +1 -1
- package/dist/shims/app.d.ts +37 -4
- package/dist/shims/app.js +50 -1
- package/dist/shims/app.js.map +1 -0
- package/dist/shims/cache-for-request.js.map +1 -1
- package/dist/shims/cache-runtime.js +20 -8
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +15 -3
- package/dist/shims/cache.js +99 -15
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/client-hook-error.js.map +1 -1
- package/dist/shims/compat-router.js.map +1 -1
- package/dist/shims/config.js.map +1 -1
- package/dist/shims/constants.js.map +1 -1
- package/dist/shims/document.js.map +1 -1
- package/dist/shims/dynamic.d.ts +18 -10
- package/dist/shims/dynamic.js +107 -51
- package/dist/shims/dynamic.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +35 -6
- package/dist/shims/error-boundary.js +118 -33
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +22 -1
- package/dist/shims/fetch-cache.js +124 -13
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/form.js +3 -1
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/head.d.ts +3 -1
- package/dist/shims/head.js +28 -16
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +4 -2
- package/dist/shims/headers.js +24 -7
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-context.js.map +1 -1
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/image-config.d.ts +14 -1
- package/dist/shims/image-config.js +24 -1
- package/dist/shims/image-config.js.map +1 -1
- package/dist/shims/image.js +15 -2
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/als-registry.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +1 -0
- package/dist/shims/internal/app-router-context.js.map +1 -1
- package/dist/shims/internal/cookie-serialize.js.map +1 -1
- package/dist/shims/internal/make-hanging-promise.d.ts +1 -1
- package/dist/shims/internal/make-hanging-promise.js +1 -1
- package/dist/shims/internal/make-hanging-promise.js.map +1 -1
- package/dist/shims/internal/parse-cookie-header.js.map +1 -1
- package/dist/shims/internal/utils.js.map +1 -1
- package/dist/shims/internal/work-unit-async-storage.js +2 -2
- package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
- package/dist/shims/layout-segment-context.js.map +1 -1
- package/dist/shims/legacy-image.js.map +1 -1
- package/dist/shims/link-prefetch.d.ts +34 -0
- package/dist/shims/link-prefetch.js +40 -0
- package/dist/shims/link-prefetch.js.map +1 -0
- package/dist/shims/link.d.ts +27 -4
- package/dist/shims/link.js +91 -27
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +22 -1
- package/dist/shims/navigation.js +30 -15
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.js.map +1 -1
- package/dist/shims/offline.js.map +1 -1
- package/dist/shims/readonly-url-search-params.js.map +1 -1
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/root-params.js.map +1 -1
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +38 -2
- package/dist/shims/router.js +45 -17
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script-nonce-context.js.map +1 -1
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +10 -14
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +6 -1
- package/dist/shims/slot.js +20 -7
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/thenable-params.js.map +1 -1
- package/dist/shims/unified-request-context.js +3 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/shims/url-utils.d.ts +2 -1
- package/dist/shims/url-utils.js +10 -1
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/shims/use-merged-ref.js.map +1 -1
- package/dist/shims/web-vitals.d.ts +4 -21
- package/dist/shims/web-vitals.js +19 -6
- package/dist/shims/web-vitals.js.map +1 -1
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/cache-control-metadata.js.map +1 -1
- package/dist/utils/domain-locale.js.map +1 -1
- package/dist/utils/encode-cache-tag.d.ts +31 -0
- package/dist/utils/encode-cache-tag.js +38 -0
- package/dist/utils/encode-cache-tag.js.map +1 -0
- package/dist/utils/error-cause.js.map +1 -1
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/lazy-chunks.js.map +1 -1
- package/dist/utils/manifest-paths.js.map +1 -1
- package/dist/utils/mdx-scan.js.map +1 -1
- package/dist/utils/navigation-signal.d.ts +6 -0
- package/dist/utils/navigation-signal.js +14 -0
- package/dist/utils/navigation-signal.js.map +1 -0
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/public-routes.js.map +1 -1
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/safe-json-file.js.map +1 -1
- package/dist/utils/text-stream.js.map +1 -1
- package/dist/utils/vinext-root.js.map +1 -1
- package/package.json +6 -4
package/dist/shims/router.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { RouterContext } from "./internal/router-context.js";
|
|
3
3
|
import { isValidModulePath } from "../client/validate-module-path.js";
|
|
4
|
-
import {
|
|
4
|
+
import { installWindowNext } from "../client/window-next.js";
|
|
5
|
+
import { isHashOnlyBrowserUrlChange, toBrowserNavigationHref, toSameOriginAppPath } from "./url-utils.js";
|
|
5
6
|
import { addLocalePrefix, getDomainLocaleUrl } from "../utils/domain-locale.js";
|
|
6
7
|
import { addQueryParam, appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
7
8
|
import { createElement, useCallback, useEffect, useMemo, useState } from "react";
|
|
@@ -93,13 +94,7 @@ function resolveHashUrl(url) {
|
|
|
93
94
|
function isHashOnlyChange(href) {
|
|
94
95
|
if (href.startsWith("#")) return true;
|
|
95
96
|
if (typeof window === "undefined") return false;
|
|
96
|
-
|
|
97
|
-
const current = new URL(window.location.href);
|
|
98
|
-
const next = new URL(href, window.location.href);
|
|
99
|
-
return current.pathname === next.pathname && current.search === next.search && next.hash !== "";
|
|
100
|
-
} catch {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
97
|
+
return isHashOnlyBrowserUrlChange(href, window.location.href, __basePath);
|
|
103
98
|
}
|
|
104
99
|
/** Scroll to hash target element, or top if no hash */
|
|
105
100
|
function scrollToHash(hash) {
|
|
@@ -402,8 +397,8 @@ function useRouter() {
|
|
|
402
397
|
resolved = localPath;
|
|
403
398
|
}
|
|
404
399
|
const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);
|
|
405
|
-
if (isHashOnlyChange(
|
|
406
|
-
const eventUrl = resolveHashUrl(
|
|
400
|
+
if (isHashOnlyChange(full)) {
|
|
401
|
+
const eventUrl = resolveHashUrl(full);
|
|
407
402
|
routerEvents.emit("hashChangeStart", eventUrl, { shallow: options?.shallow ?? false });
|
|
408
403
|
const hash = resolved.includes("#") ? resolved.slice(resolved.indexOf("#")) : "";
|
|
409
404
|
window.history.pushState({}, "", resolved.startsWith("#") ? resolved : full);
|
|
@@ -443,8 +438,8 @@ function useRouter() {
|
|
|
443
438
|
resolved = localPath;
|
|
444
439
|
}
|
|
445
440
|
const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);
|
|
446
|
-
if (isHashOnlyChange(
|
|
447
|
-
const eventUrl = resolveHashUrl(
|
|
441
|
+
if (isHashOnlyChange(full)) {
|
|
442
|
+
const eventUrl = resolveHashUrl(full);
|
|
448
443
|
routerEvents.emit("hashChangeStart", eventUrl, { shallow: options?.shallow ?? false });
|
|
449
444
|
const hash = resolved.includes("#") ? resolved.slice(resolved.indexOf("#")) : "";
|
|
450
445
|
window.history.replaceState({}, "", resolved.startsWith("#") ? resolved : full);
|
|
@@ -561,6 +556,38 @@ function wrapWithRouterContext(element) {
|
|
|
561
556
|
});
|
|
562
557
|
return createElement(RouterContext.Provider, { value: routerValue }, element);
|
|
563
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* Higher-order component that injects the Pages Router `router` instance as
|
|
561
|
+
* a `router` prop into a wrapped component. Primarily used by class
|
|
562
|
+
* components (which cannot call hooks) to access the router. The wrapped
|
|
563
|
+
* component receives the same props as the original, minus `router`, which
|
|
564
|
+
* is filled in by the HOC.
|
|
565
|
+
*
|
|
566
|
+
* Ported from Next.js: packages/next/src/client/with-router.tsx
|
|
567
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/client/with-router.tsx
|
|
568
|
+
*
|
|
569
|
+
* Differences from Next.js:
|
|
570
|
+
* - We type the composed component as `ComponentType<P>` instead of
|
|
571
|
+
* `NextComponentType<C, any, P>` because vinext does not expose
|
|
572
|
+
* `NextComponentType` from this shim. The runtime shape (and the props
|
|
573
|
+
* the wrapper forwards) is identical.
|
|
574
|
+
* - We forward `getInitialProps` and `origGetInitialProps` from the
|
|
575
|
+
* composed component so `_app` parity holds for class components that
|
|
576
|
+
* define `getInitialProps`.
|
|
577
|
+
*/
|
|
578
|
+
function withRouter(ComposedComponent) {
|
|
579
|
+
function WithRouterWrapper(props) {
|
|
580
|
+
return createElement(ComposedComponent, {
|
|
581
|
+
router: useRouter(),
|
|
582
|
+
...props
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
const composed = ComposedComponent;
|
|
586
|
+
WithRouterWrapper.getInitialProps = composed.getInitialProps;
|
|
587
|
+
WithRouterWrapper.origGetInitialProps = composed.origGetInitialProps;
|
|
588
|
+
if (process.env.NODE_ENV !== "production") WithRouterWrapper.displayName = `withRouter(${composed.displayName || composed.name || "Unknown"})`;
|
|
589
|
+
return WithRouterWrapper;
|
|
590
|
+
}
|
|
564
591
|
const Router = {
|
|
565
592
|
push: async (url, as, options) => {
|
|
566
593
|
let resolved = resolveNavigationTarget(url, as, options?.locale);
|
|
@@ -573,8 +600,8 @@ const Router = {
|
|
|
573
600
|
resolved = localPath;
|
|
574
601
|
}
|
|
575
602
|
const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);
|
|
576
|
-
if (isHashOnlyChange(
|
|
577
|
-
const eventUrl = resolveHashUrl(
|
|
603
|
+
if (isHashOnlyChange(full)) {
|
|
604
|
+
const eventUrl = resolveHashUrl(full);
|
|
578
605
|
routerEvents.emit("hashChangeStart", eventUrl, { shallow: options?.shallow ?? false });
|
|
579
606
|
const hash = resolved.includes("#") ? resolved.slice(resolved.indexOf("#")) : "";
|
|
580
607
|
window.history.pushState({}, "", resolved.startsWith("#") ? resolved : full);
|
|
@@ -612,8 +639,8 @@ const Router = {
|
|
|
612
639
|
resolved = localPath;
|
|
613
640
|
}
|
|
614
641
|
const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);
|
|
615
|
-
if (isHashOnlyChange(
|
|
616
|
-
const eventUrl = resolveHashUrl(
|
|
642
|
+
if (isHashOnlyChange(full)) {
|
|
643
|
+
const eventUrl = resolveHashUrl(full);
|
|
617
644
|
routerEvents.emit("hashChangeStart", eventUrl, { shallow: options?.shallow ?? false });
|
|
618
645
|
const hash = resolved.includes("#") ? resolved.slice(resolved.indexOf("#")) : "";
|
|
619
646
|
window.history.replaceState({}, "", resolved.startsWith("#") ? resolved : full);
|
|
@@ -655,7 +682,8 @@ const Router = {
|
|
|
655
682
|
},
|
|
656
683
|
events: routerEvents
|
|
657
684
|
};
|
|
685
|
+
if (typeof window !== "undefined") installWindowNext({ router: Router });
|
|
658
686
|
//#endregion
|
|
659
|
-
export { _registerRouterStateAccessors, applyNavigationLocale, Router as default, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, wrapWithRouterContext };
|
|
687
|
+
export { _registerRouterStateAccessors, applyNavigationLocale, Router as default, isExternalUrl, isHashOnlyChange, setSSRContext, useRouter, withRouter, wrapWithRouterContext };
|
|
660
688
|
|
|
661
689
|
//# sourceMappingURL=router.js.map
|
package/dist/shims/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","names":[],"sources":["../../src/shims/router.ts"],"sourcesContent":["/**\n * next/router shim\n *\n * Provides useRouter() hook and Router singleton for Pages Router.\n * Backed by the browser History API. Supports client-side navigation\n * by fetching new page data and re-rendering the React root.\n */\nimport { useState, useEffect, useCallback, useMemo, createElement, type ReactElement } from \"react\";\nimport { RouterContext } from \"./internal/router-context.js\";\nimport type { VinextNextData } from \"../client/vinext-next-data.js\";\nimport { isValidModulePath } from \"../client/validate-module-path.js\";\nimport { toBrowserNavigationHref, toSameOriginAppPath } from \"./url-utils.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport { addLocalePrefix, getDomainLocaleUrl, type DomainLocale } from \"../utils/domain-locale.js\";\nimport {\n addQueryParam,\n appendSearchParamsToUrl,\n type UrlQuery,\n urlQueryToSearchParams,\n} from \"../utils/query.js\";\n\n/** basePath from next.config.js, injected by the plugin at build time */\nconst __basePath: string = process.env.__NEXT_ROUTER_BASEPATH ?? \"\";\n\ntype BeforePopStateCallback = (state: {\n url: string;\n as: string;\n options: { shallow: boolean };\n}) => boolean;\n\nexport type NextRouter = {\n /** Current pathname */\n pathname: string;\n /** Current route pattern (e.g., \"/posts/[id]\") */\n route: string;\n /** Query parameters */\n query: Record<string, string | string[]>;\n /** Full URL including query string */\n asPath: string;\n /** Base path */\n basePath: string;\n /** Current locale */\n locale?: string;\n /** Available locales */\n locales?: string[];\n /** Default locale */\n defaultLocale?: string;\n /** Configured domain locales */\n domainLocales?: VinextNextData[\"domainLocales\"];\n /** Whether the router is ready */\n isReady: boolean;\n /** Whether this is a preview */\n isPreview: boolean;\n /** Whether this is a fallback page */\n isFallback: boolean;\n\n /** Navigate to a new URL */\n push(url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean>;\n /** Replace current URL */\n replace(url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean>;\n /** Go back */\n back(): void;\n /** Reload the page */\n reload(): void;\n /** Prefetch a page (injects <link rel=\"prefetch\">) */\n prefetch(url: string): Promise<void>;\n /** Register a callback to run before popstate navigation */\n beforePopState(cb: BeforePopStateCallback): void;\n /** Listen for route changes */\n events: RouterEvents;\n};\n\ntype UrlObject = {\n pathname?: string;\n query?: UrlQuery;\n};\n\ntype TransitionOptions = {\n shallow?: boolean;\n scroll?: boolean;\n locale?: string;\n};\n\ntype RouterEvents = {\n on(event: string, handler: (...args: unknown[]) => void): void;\n off(event: string, handler: (...args: unknown[]) => void): void;\n emit(event: string, ...args: unknown[]): void;\n};\n\nfunction createRouterEvents(): RouterEvents {\n const listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n return {\n on(event: string, handler: (...args: unknown[]) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n (listeners.get(event) as Set<(...args: unknown[]) => void>).add(handler);\n },\n off(event: string, handler: (...args: unknown[]) => void) {\n listeners.get(event)?.delete(handler);\n },\n emit(event: string, ...args: unknown[]) {\n listeners.get(event)?.forEach((handler) => handler(...args));\n },\n };\n}\n\n// Singleton events instance\nconst routerEvents = createRouterEvents();\n\nfunction resolveUrl(url: string | UrlObject): string {\n if (typeof url === \"string\") return url;\n let result = url.pathname ?? \"/\";\n if (url.query) {\n const params = urlQueryToSearchParams(url.query);\n result = appendSearchParamsToUrl(result, params);\n }\n return result;\n}\n\n/**\n * When `as` is provided, use it as the navigation target. This is a\n * simplification: Next.js keeps `url` and `as` as separate values (url for\n * data fetching, as for the browser URL). We collapse them because vinext's\n * navigateClient() fetches HTML from the target URL, so `as` must be a\n * server-resolvable path. Purely decorative `as` values are not supported.\n */\nfunction resolveNavigationTarget(\n url: string | UrlObject,\n as: string | undefined,\n locale: string | undefined,\n): string {\n return applyNavigationLocale(as ?? resolveUrl(url), locale);\n}\n\nfunction getDomainLocales(): readonly DomainLocale[] | undefined {\n return (window.__NEXT_DATA__ as VinextNextData | undefined)?.domainLocales;\n}\n\nfunction getCurrentHostname(): string | undefined {\n return window.location?.hostname;\n}\n\nfunction getDomainLocalePath(url: string, locale: string): string | undefined {\n return getDomainLocaleUrl(url, locale, {\n basePath: __basePath,\n currentHostname: getCurrentHostname(),\n domainItems: getDomainLocales(),\n });\n}\n\n/**\n * Apply locale prefix to a URL for client-side navigation.\n * Same logic as Link's applyLocaleToHref but reads from window globals.\n */\nexport function applyNavigationLocale(url: string, locale?: string): string {\n if (!locale || typeof window === \"undefined\") return url;\n // Absolute and protocol-relative URLs must not be prefixed — locale\n // only applies to local paths.\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\") || url.startsWith(\"//\")) {\n return url;\n }\n\n const domainLocalePath = getDomainLocalePath(url, locale);\n if (domainLocalePath) return domainLocalePath;\n\n return addLocalePrefix(url, locale, window.__VINEXT_DEFAULT_LOCALE__ ?? \"\");\n}\n\n/** Check if a URL is external (any URL scheme per RFC 3986, or protocol-relative) */\nexport function isExternalUrl(url: string): boolean {\n return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith(\"//\");\n}\n\n/** Resolve a hash URL to a basePath-stripped app URL for event payloads */\nfunction resolveHashUrl(url: string): string {\n if (typeof window === \"undefined\") return url;\n if (url.startsWith(\"#\"))\n return stripBasePath(window.location.pathname, __basePath) + window.location.search + url;\n // Full-path hash URL — strip basePath for consistency with other events\n try {\n const parsed = new URL(url, window.location.href);\n return stripBasePath(parsed.pathname, __basePath) + parsed.search + parsed.hash;\n } catch {\n return url;\n }\n}\n\n/** Check if a href is only a hash change relative to the current URL */\nexport function isHashOnlyChange(href: string): boolean {\n if (href.startsWith(\"#\")) return true;\n if (typeof window === \"undefined\") return false;\n try {\n const current = new URL(window.location.href);\n const next = new URL(href, window.location.href);\n return current.pathname === next.pathname && current.search === next.search && next.hash !== \"\";\n } catch {\n return false;\n }\n}\n\n/** Scroll to hash target element, or top if no hash */\nfunction scrollToHash(hash: string): void {\n if (!hash || hash === \"#\") {\n window.scrollTo(0, 0);\n return;\n }\n const el = document.getElementById(hash.slice(1));\n if (el) el.scrollIntoView({ behavior: \"auto\" });\n}\n\n/** Save current scroll position into history state for back/forward restoration */\nfunction saveScrollPosition(): void {\n const state = window.history.state ?? {};\n window.history.replaceState(\n { ...state, __vinext_scrollX: window.scrollX, __vinext_scrollY: window.scrollY },\n \"\",\n );\n}\n\n/** Restore scroll position from history state */\nfunction restoreScrollPosition(state: unknown): void {\n if (state && typeof state === \"object\" && \"__vinext_scrollY\" in state) {\n const { __vinext_scrollX: x, __vinext_scrollY: y } = state as {\n __vinext_scrollX: number;\n __vinext_scrollY: number;\n };\n requestAnimationFrame(() => window.scrollTo(x, y));\n }\n}\n\n/**\n * SSR context - set by the dev server before rendering each page.\n */\ntype SSRContext = {\n pathname: string;\n query: Record<string, string | string[]>;\n asPath: string;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n domainLocales?: VinextNextData[\"domainLocales\"];\n};\n\n// ---------------------------------------------------------------------------\n// Server-side SSR state uses a registration pattern so this module can be\n// bundled for the browser. The ALS-backed implementation lives in\n// router-state.ts (server-only) and registers itself on import.\n// ---------------------------------------------------------------------------\n\nlet _ssrContext: SSRContext | null = null;\n\nlet _getSSRContext = (): SSRContext | null => _ssrContext;\nlet _setSSRContextImpl = (ctx: SSRContext | null): void => {\n _ssrContext = ctx;\n};\n\n/**\n * Register ALS-backed state accessors. Called by router-state.ts on import.\n * @internal\n */\nexport function _registerRouterStateAccessors(accessors: {\n getSSRContext: () => SSRContext | null;\n setSSRContext: (ctx: SSRContext | null) => void;\n}): void {\n _getSSRContext = accessors.getSSRContext;\n _setSSRContextImpl = accessors.setSSRContext;\n}\n\nexport function setSSRContext(ctx: SSRContext | null): void {\n _setSSRContextImpl(ctx);\n}\n\n/**\n * Extract param names from a Next.js route pattern.\n * E.g., \"/posts/[id]\" → [\"id\"], \"/docs/[...slug]\" → [\"slug\"],\n * \"/shop/[[...path]]\" → [\"path\"], \"/blog/[year]/[month]\" → [\"year\", \"month\"]\n * Also handles internal format: \"/posts/:id\" → [\"id\"], \"/docs/:slug+\" → [\"slug\"]\n */\nfunction extractRouteParamNames(pattern: string): string[] {\n const names: string[] = [];\n // Match Next.js bracket format: [id], [...slug], [[...slug]]\n // Accepts any non-] characters inside brackets (Next.js PARAMETER_PATTERN parity).\n const bracketMatches = pattern.matchAll(/\\[{1,2}(?:\\.\\.\\.)?([^\\]]+)\\]{1,2}/g);\n for (const m of bracketMatches) {\n names.push(m[1]);\n }\n if (names.length > 0) return names;\n // Fallback: match internal :param format (any chars except /, +, *)\n const colonMatches = pattern.matchAll(/:([^/+*]+)[+*]?/g);\n for (const m of colonMatches) {\n names.push(m[1]);\n }\n return names;\n}\n\nfunction getPathnameAndQuery(): {\n pathname: string;\n query: Record<string, string | string[]>;\n asPath: string;\n} {\n if (typeof window === \"undefined\") {\n const _ssrCtx = _getSSRContext();\n if (_ssrCtx) {\n const query: Record<string, string | string[]> = {};\n for (const [key, value] of Object.entries(_ssrCtx.query)) {\n query[key] = Array.isArray(value) ? [...value] : value;\n }\n return { pathname: _ssrCtx.pathname, query, asPath: _ssrCtx.asPath };\n }\n return { pathname: \"/\", query: {}, asPath: \"/\" };\n }\n const resolvedPath = stripBasePath(window.location.pathname, __basePath);\n // In Next.js, router.pathname is the route pattern (e.g., \"/posts/[id]\"),\n // not the resolved path (\"/posts/42\"). __NEXT_DATA__.page holds the route\n // pattern and is updated by navigateClient() on every client-side navigation.\n const pathname = window.__NEXT_DATA__?.page ?? resolvedPath;\n const routeQuery: Record<string, string | string[]> = {};\n // Include dynamic route params from __NEXT_DATA__ (e.g., { id: \"42\" } from /posts/[id]).\n // Only include keys that are part of the route pattern (not stale query params).\n const nextData = window.__NEXT_DATA__;\n if (nextData && nextData.query && nextData.page) {\n const routeParamNames = extractRouteParamNames(nextData.page);\n for (const key of routeParamNames) {\n const value = nextData.query[key];\n if (typeof value === \"string\") {\n routeQuery[key] = value;\n } else if (Array.isArray(value)) {\n routeQuery[key] = [...value];\n }\n }\n }\n // URL search params always reflect the current URL\n const searchQuery: Record<string, string | string[]> = {};\n const params = new URLSearchParams(window.location.search);\n for (const [key, value] of params) {\n addQueryParam(searchQuery, key, value);\n }\n const query = { ...searchQuery, ...routeQuery };\n // asPath uses the resolved browser path, not the route pattern\n const asPath = resolvedPath + window.location.search + window.location.hash;\n return { pathname, query, asPath };\n}\n\n/**\n * Error thrown when a navigation is superseded by a newer one.\n * Matches Next.js's convention of an Error with `.cancelled = true`.\n */\nclass NavigationCancelledError extends Error {\n cancelled = true;\n constructor(route: string) {\n super(`Abort fetching component for route: \"${route}\"`);\n this.name = \"NavigationCancelledError\";\n }\n}\n\n/**\n * Error thrown after queueing a hard navigation fallback for a known failure\n * mode. Callers can use this to avoid scheduling the same hard navigation twice.\n */\nclass HardNavigationScheduledError extends Error {\n hardNavigationScheduled = true;\n constructor(message: string) {\n super(message);\n this.name = \"HardNavigationScheduledError\";\n }\n}\n\n/**\n * Monotonically increasing ID for tracking the current navigation.\n * Each call to navigateClient() increments this and captures the value.\n * After each async boundary, the navigation checks whether it is still\n * the active one. If a newer navigation has started, the stale one\n * throws NavigationCancelledError so the caller can emit routeChangeError\n * and skip routeChangeComplete.\n *\n * Replaces the old boolean `_navInProgress` guard which silently dropped\n * the second navigation, causing URL/content mismatch.\n */\nlet _navigationId = 0;\n\n/** AbortController for the in-flight fetch, so superseded navigations abort network I/O. */\nlet _activeAbortController: AbortController | null = null;\n\nfunction scheduleHardNavigationAndThrow(url: string, message: string): never {\n if (typeof window === \"undefined\") {\n throw new HardNavigationScheduledError(message);\n }\n window.location.href = url;\n throw new HardNavigationScheduledError(message);\n}\n\n/**\n * Perform client-side navigation: fetch the target page's HTML,\n * extract __NEXT_DATA__, and re-render the React root.\n *\n * Throws NavigationCancelledError if a newer navigation supersedes this one.\n * Throws on hard-navigation failures (non-OK response, missing data) so the\n * caller can distinguish success from failure for event emission.\n */\nasync function navigateClient(url: string): Promise<void> {\n if (typeof window === \"undefined\") return;\n\n const root = window.__VINEXT_ROOT__;\n if (!root) {\n // No React root yet — fall back to hard navigation\n window.location.href = url;\n return;\n }\n\n // Cancel any in-flight navigation (abort its fetch, mark it stale)\n _activeAbortController?.abort();\n const controller = new AbortController();\n _activeAbortController = controller;\n\n const navId = ++_navigationId;\n\n /** Check if this navigation is still the active one. If not, throw. */\n function assertStillCurrent(): void {\n if (navId !== _navigationId) {\n throw new NavigationCancelledError(url);\n }\n }\n\n try {\n // Fetch the target page's SSR HTML\n let res: Response;\n try {\n res = await fetch(url, {\n headers: { Accept: \"text/html\" },\n signal: controller.signal,\n });\n } catch (err: unknown) {\n // AbortError means a newer navigation cancelled this fetch\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new NavigationCancelledError(url);\n }\n throw err;\n }\n assertStillCurrent();\n\n if (!res.ok) {\n // Set window.location.href first so the browser navigates to the correct\n // page even if the caller suppresses the error. The assignment schedules\n // the navigation asynchronously (as a task), so synchronous routeChangeError\n // listeners still run — and observe the error — before the page unloads.\n // Contract: routeChangeError listeners MUST be synchronous; async listeners\n // will not fire before the navigation completes. Callers (runNavigateClient)\n // must NOT schedule a second hard navigation — this assignment already queues\n // the browser fallback, and the helper-level HardNavigationScheduledError\n // makes that contract explicit to callers.\n scheduleHardNavigationAndThrow(url, `Navigation failed: ${res.status} ${res.statusText}`);\n }\n\n const html = await res.text();\n assertStillCurrent();\n\n // Extract __NEXT_DATA__ from the HTML\n const match = html.match(/<script>window\\.__NEXT_DATA__\\s*=\\s*(.*?)<\\/script>/);\n if (!match) {\n scheduleHardNavigationAndThrow(url, \"Navigation failed: missing __NEXT_DATA__ in response\");\n }\n\n const nextData = JSON.parse(match[1]);\n const { pageProps } = nextData.props;\n // Defer writing window.__NEXT_DATA__ until just before root.render() —\n // writing it here would let a stale navigation briefly pollute the global\n // between this assertStillCurrent() and the next one after await import().\n\n // Get the page module URL from __NEXT_DATA__.__vinext (preferred),\n // or fall back to parsing the hydration script\n let pageModuleUrl: string | undefined = nextData.__vinext?.pageModuleUrl;\n\n if (!pageModuleUrl) {\n // Legacy fallback: try to find the module URL in the inline script\n const moduleMatch = html.match(/import\\(\"([^\"]+)\"\\);\\s*\\n\\s*const PageComponent/);\n const altMatch = html.match(/await import\\(\"([^\"]+pages\\/[^\"]+)\"\\)/);\n pageModuleUrl = moduleMatch?.[1] ?? altMatch?.[1] ?? undefined;\n }\n\n if (!pageModuleUrl) {\n scheduleHardNavigationAndThrow(url, \"Navigation failed: no page module URL found\");\n }\n\n // Validate the module URL before importing — defense-in-depth against\n // unexpected __NEXT_DATA__ or malformed HTML responses\n if (!isValidModulePath(pageModuleUrl)) {\n console.error(\"[vinext] Blocked import of invalid page module path:\", pageModuleUrl);\n scheduleHardNavigationAndThrow(url, \"Navigation failed: invalid page module path\");\n }\n\n // Dynamically import the new page module\n const pageModule = await import(/* @vite-ignore */ pageModuleUrl);\n assertStillCurrent();\n\n const PageComponent = pageModule.default;\n\n if (!PageComponent) {\n scheduleHardNavigationAndThrow(url, \"Navigation failed: page module has no default export\");\n }\n\n // Import React for createElement\n const React = (await import(\"react\")).default;\n assertStillCurrent();\n\n // Re-render with the new page, loading _app if needed\n let AppComponent = window.__VINEXT_APP__;\n const appModuleUrl: string | undefined = nextData.__vinext?.appModuleUrl;\n\n if (!AppComponent && appModuleUrl) {\n if (!isValidModulePath(appModuleUrl)) {\n console.error(\"[vinext] Blocked import of invalid app module path:\", appModuleUrl);\n } else {\n try {\n const appModule = await import(/* @vite-ignore */ appModuleUrl);\n AppComponent = appModule.default;\n window.__VINEXT_APP__ = AppComponent;\n } catch {\n // _app not available — continue without it\n }\n }\n }\n assertStillCurrent();\n\n let element;\n if (AppComponent) {\n element = React.createElement(AppComponent, {\n Component: PageComponent,\n pageProps,\n });\n } else {\n element = React.createElement(PageComponent, pageProps);\n }\n\n // Wrap with RouterContext.Provider so next/compat/router works\n element = wrapWithRouterContext(element);\n\n // Commit __NEXT_DATA__ only after all assertStillCurrent() checks have passed,\n // so a stale navigation can never pollute the global.\n // INVARIANT: Everything after the final assertStillCurrent() above (the\n // checkpoint immediately after the optional _app import) through\n // root.render() is synchronous. If any step here ever becomes async, add\n // another assertStillCurrent() before writing __NEXT_DATA__.\n window.__NEXT_DATA__ = nextData;\n root.render(element);\n } finally {\n // Clean up the abort controller if this navigation is still the active one\n if (navId === _navigationId) {\n _activeAbortController = null;\n }\n }\n}\n\n/**\n * Run navigateClient and handle errors: emit routeChangeError on failure,\n * and fall back to a hard navigation for non-cancel errors so the browser\n * recovers to a consistent state.\n *\n * Returns:\n * - \"completed\" — navigation finished, caller should emit routeChangeComplete\n * - \"cancelled\" — superseded by a newer navigation, caller should return true\n * without emitting routeChangeComplete (matches Next.js behaviour)\n * - \"failed\" — genuine error, caller should return false (hard nav is already\n * scheduled as recovery)\n */\nasync function runNavigateClient(\n fullUrl: string,\n resolvedUrl: string,\n): Promise<\"completed\" | \"cancelled\" | \"failed\"> {\n try {\n await navigateClient(fullUrl);\n return \"completed\";\n } catch (err: unknown) {\n routerEvents.emit(\"routeChangeError\", err, resolvedUrl, { shallow: false });\n if (err instanceof NavigationCancelledError) {\n return \"cancelled\";\n }\n // Genuine error (network, parse, import failure): fall back to a hard\n // navigation so the browser lands on the correct page. Known failure modes\n // throw HardNavigationScheduledError, and this guard skips those; only\n // unexpected failures (parse, import, render) need recovery here.\n if (typeof window !== \"undefined\" && !(err instanceof HardNavigationScheduledError)) {\n window.location.href = fullUrl;\n }\n return \"failed\";\n }\n}\n\n/**\n * Build the full router value object from the current pathname, query, asPath,\n * and a set of navigation methods. Shared by useRouter() (which passes\n * hook-derived callbacks) and wrapWithRouterContext() (which passes the Router\n * singleton methods) so the shape stays in sync.\n */\nfunction buildRouterValue(\n pathname: string,\n query: Record<string, string | string[]>,\n asPath: string,\n methods: {\n push: NextRouter[\"push\"];\n replace: NextRouter[\"replace\"];\n back: NextRouter[\"back\"];\n reload: NextRouter[\"reload\"];\n prefetch: NextRouter[\"prefetch\"];\n beforePopState: NextRouter[\"beforePopState\"];\n },\n): NextRouter {\n const _ssrState = _getSSRContext();\n const nextData =\n typeof window !== \"undefined\"\n ? (window.__NEXT_DATA__ as VinextNextData | undefined)\n : undefined;\n const locale = typeof window === \"undefined\" ? _ssrState?.locale : window.__VINEXT_LOCALE__;\n const locales = typeof window === \"undefined\" ? _ssrState?.locales : window.__VINEXT_LOCALES__;\n const defaultLocale =\n typeof window === \"undefined\" ? _ssrState?.defaultLocale : window.__VINEXT_DEFAULT_LOCALE__;\n const domainLocales =\n typeof window === \"undefined\" ? _ssrState?.domainLocales : nextData?.domainLocales;\n\n const route = typeof window !== \"undefined\" ? (nextData?.page ?? pathname) : pathname;\n\n return {\n pathname,\n route,\n query,\n asPath,\n basePath: __basePath,\n locale,\n locales,\n defaultLocale,\n domainLocales,\n isReady: true,\n isPreview: false,\n isFallback: typeof window !== \"undefined\" && nextData?.isFallback === true,\n ...methods,\n events: routerEvents,\n };\n}\n\n/**\n * useRouter hook - Pages Router compatible.\n */\nexport function useRouter(): NextRouter {\n const [{ pathname, query, asPath }, setState] = useState(getPathnameAndQuery);\n\n // Popstate is handled by the module-level listener below so beforePopState()\n // is consistently enforced even when multiple components mount useRouter().\n useEffect(() => {\n const onNavigate = ((_e: CustomEvent) => {\n setState(getPathnameAndQuery());\n }) as EventListener;\n window.addEventListener(\"vinext:navigate\", onNavigate);\n return () => window.removeEventListener(\"vinext:navigate\", onNavigate);\n }, []);\n\n const push = useCallback(\n async (url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean> => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs — delegate to browser (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.assign(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change — no page fetch needed\n if (isHashOnlyChange(resolved)) {\n const eventUrl = resolveHashUrl(resolved);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.pushState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n setState(getPathnameAndQuery());\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n saveScrollPosition();\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.pushState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n setState(getPathnameAndQuery());\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n // Scroll: handle hash target, else scroll to top unless scroll:false\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n [],\n );\n\n const replace = useCallback(\n async (url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean> => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs — delegate to browser (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.replace(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change — no page fetch needed\n if (isHashOnlyChange(resolved)) {\n const eventUrl = resolveHashUrl(resolved);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.replaceState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n setState(getPathnameAndQuery());\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.replaceState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n setState(getPathnameAndQuery());\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n // Scroll: handle hash target, else scroll to top unless scroll:false\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n [],\n );\n\n const back = useCallback(() => {\n window.history.back();\n }, []);\n\n const reload = useCallback(() => {\n window.location.reload();\n }, []);\n\n const prefetch = useCallback(async (url: string): Promise<void> => {\n // Inject a <link rel=\"prefetch\"> for the target page\n if (typeof document !== \"undefined\") {\n const link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = url;\n link.as = \"document\";\n document.head.appendChild(link);\n }\n }, []);\n\n const router = useMemo(\n (): NextRouter =>\n buildRouterValue(pathname, query, asPath, {\n push,\n replace,\n back,\n reload,\n prefetch,\n beforePopState: (cb: BeforePopStateCallback) => {\n _beforePopStateCb = cb;\n },\n }),\n [pathname, query, asPath, push, replace, back, reload, prefetch],\n );\n\n return router;\n}\n\n// beforePopState callback: called before handling browser back/forward.\n// If it returns false, the navigation is cancelled.\nlet _beforePopStateCb: BeforePopStateCallback | undefined;\n\n// Track pathname+search for detecting hash-only back/forward in the popstate\n// handler. Updated after every pushState/replaceState so that popstate can\n// compare the previous value with the (already-changed) window.location.\nlet _lastPathnameAndSearch =\n typeof window !== \"undefined\" ? window.location.pathname + window.location.search : \"\";\n\n// Module-level popstate listener: handles browser back/forward by re-rendering\n// the React root with the page at the new URL. This runs regardless of whether\n// any component calls useRouter().\nif (typeof window !== \"undefined\") {\n window.addEventListener(\"popstate\", (e: PopStateEvent) => {\n const browserUrl = window.location.pathname + window.location.search;\n const appUrl = stripBasePath(window.location.pathname, __basePath) + window.location.search;\n\n // Detect hash-only back/forward: pathname+search unchanged, only hash differs.\n const isHashOnly = browserUrl === _lastPathnameAndSearch;\n\n // Check beforePopState callback\n if (_beforePopStateCb !== undefined) {\n const shouldContinue = (_beforePopStateCb as BeforePopStateCallback)({\n url: appUrl,\n as: appUrl,\n options: { shallow: false },\n });\n if (!shouldContinue) return;\n }\n\n // Update tracker only after beforePopState confirms navigation proceeds.\n // If beforePopState cancels, the tracker must retain the previous value\n // so the next popstate compares against the correct baseline.\n _lastPathnameAndSearch = browserUrl;\n\n if (isHashOnly) {\n // Hash-only back/forward — no page fetch needed\n const hashUrl = appUrl + window.location.hash;\n routerEvents.emit(\"hashChangeStart\", hashUrl, { shallow: false });\n scrollToHash(window.location.hash);\n routerEvents.emit(\"hashChangeComplete\", hashUrl, { shallow: false });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return;\n }\n\n const fullAppUrl = appUrl + window.location.hash;\n routerEvents.emit(\"routeChangeStart\", fullAppUrl, { shallow: false });\n // Note: The browser has already updated window.location by the time popstate\n // fires, so this is not truly \"before\" the URL change. In Next.js the popstate\n // handler calls replaceState to store history metadata — beforeHistoryChange\n // precedes that call, not the URL change itself. We emit it here for API\n // compatibility.\n routerEvents.emit(\"beforeHistoryChange\", fullAppUrl, { shallow: false });\n void (async () => {\n const result = await runNavigateClient(browserUrl, fullAppUrl);\n if (result === \"completed\") {\n routerEvents.emit(\"routeChangeComplete\", fullAppUrl, { shallow: false });\n restoreScrollPosition(e.state);\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n }\n // \"cancelled\": superseded by a newer navigation, so this popstate no longer wins.\n // \"failed\": runNavigateClient already scheduled the hard-navigation fallback.\n })();\n });\n}\n\n/**\n * Wrap a React element in a RouterContext.Provider so that\n * next/compat/router's useRouter() returns the real Pages Router value.\n *\n * This is a plain function, NOT a React component — it builds the router\n * value object directly from the current SSR context (server) or\n * window.location + Router singleton (client), avoiding duplicate state\n * that a hook-based component would create.\n */\nexport function wrapWithRouterContext(element: ReactElement): ReactElement {\n const { pathname, query, asPath } = getPathnameAndQuery();\n\n const routerValue = buildRouterValue(pathname, query, asPath, {\n push: Router.push,\n replace: Router.replace,\n back: Router.back,\n reload: Router.reload,\n prefetch: Router.prefetch,\n beforePopState: Router.beforePopState,\n });\n\n return createElement(RouterContext.Provider, { value: routerValue }, element) as ReactElement;\n}\n\n// Also export a default Router singleton for `import Router from 'next/router'`\nconst Router = {\n push: async (url: string | UrlObject, as?: string, options?: TransitionOptions) => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.assign(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change\n if (isHashOnlyChange(resolved)) {\n const eventUrl = resolveHashUrl(resolved);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.pushState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n saveScrollPosition();\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.pushState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n replace: async (url: string | UrlObject, as?: string, options?: TransitionOptions) => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.replace(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change\n if (isHashOnlyChange(resolved)) {\n const eventUrl = resolveHashUrl(resolved);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.replaceState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.replaceState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n back: () => window.history.back(),\n reload: () => window.location.reload(),\n prefetch: async (url: string) => {\n if (typeof document !== \"undefined\") {\n const link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = url;\n link.as = \"document\";\n document.head.appendChild(link);\n }\n },\n beforePopState: (cb: BeforePopStateCallback) => {\n _beforePopStateCb = cb;\n },\n events: routerEvents,\n};\n\nexport default Router;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router.js","names":[],"sources":["../../src/shims/router.ts"],"sourcesContent":["/**\n * next/router shim\n *\n * Provides useRouter() hook and Router singleton for Pages Router.\n * Backed by the browser History API. Supports client-side navigation\n * by fetching new page data and re-rendering the React root.\n */\nimport {\n useState,\n useEffect,\n useCallback,\n useMemo,\n createElement,\n type ReactElement,\n type ComponentType,\n} from \"react\";\nimport { RouterContext } from \"./internal/router-context.js\";\nimport type { VinextNextData } from \"../client/vinext-next-data.js\";\nimport { isValidModulePath } from \"../client/validate-module-path.js\";\nimport { installWindowNext, type PagesRouterPublicInstance } from \"../client/window-next.js\";\nimport {\n isHashOnlyBrowserUrlChange,\n toBrowserNavigationHref,\n toSameOriginAppPath,\n} from \"./url-utils.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport { addLocalePrefix, getDomainLocaleUrl, type DomainLocale } from \"../utils/domain-locale.js\";\nimport {\n addQueryParam,\n appendSearchParamsToUrl,\n type UrlQuery,\n urlQueryToSearchParams,\n} from \"../utils/query.js\";\n\n/** basePath from next.config.js, injected by the plugin at build time */\nconst __basePath: string = process.env.__NEXT_ROUTER_BASEPATH ?? \"\";\n\ntype BeforePopStateCallback = (state: {\n url: string;\n as: string;\n options: { shallow: boolean };\n}) => boolean;\n\nexport type NextRouter = {\n /** Current pathname */\n pathname: string;\n /** Current route pattern (e.g., \"/posts/[id]\") */\n route: string;\n /** Query parameters */\n query: Record<string, string | string[]>;\n /** Full URL including query string */\n asPath: string;\n /** Base path */\n basePath: string;\n /** Current locale */\n locale?: string;\n /** Available locales */\n locales?: string[];\n /** Default locale */\n defaultLocale?: string;\n /** Configured domain locales */\n domainLocales?: VinextNextData[\"domainLocales\"];\n /** Whether the router is ready */\n isReady: boolean;\n /** Whether this is a preview */\n isPreview: boolean;\n /** Whether this is a fallback page */\n isFallback: boolean;\n\n /** Navigate to a new URL */\n push(url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean>;\n /** Replace current URL */\n replace(url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean>;\n /** Go back */\n back(): void;\n /** Reload the page */\n reload(): void;\n /** Prefetch a page (injects <link rel=\"prefetch\">) */\n prefetch(url: string): Promise<void>;\n /** Register a callback to run before popstate navigation */\n beforePopState(cb: BeforePopStateCallback): void;\n /** Listen for route changes */\n events: RouterEvents;\n};\n\ntype UrlObject = {\n pathname?: string;\n query?: UrlQuery;\n};\n\ntype TransitionOptions = {\n shallow?: boolean;\n scroll?: boolean;\n locale?: string;\n};\n\ntype RouterEvents = {\n on(event: string, handler: (...args: unknown[]) => void): void;\n off(event: string, handler: (...args: unknown[]) => void): void;\n emit(event: string, ...args: unknown[]): void;\n};\n\nfunction createRouterEvents(): RouterEvents {\n const listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n return {\n on(event: string, handler: (...args: unknown[]) => void) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n (listeners.get(event) as Set<(...args: unknown[]) => void>).add(handler);\n },\n off(event: string, handler: (...args: unknown[]) => void) {\n listeners.get(event)?.delete(handler);\n },\n emit(event: string, ...args: unknown[]) {\n listeners.get(event)?.forEach((handler) => handler(...args));\n },\n };\n}\n\n// Singleton events instance\nconst routerEvents = createRouterEvents();\n\nfunction resolveUrl(url: string | UrlObject): string {\n if (typeof url === \"string\") return url;\n let result = url.pathname ?? \"/\";\n if (url.query) {\n const params = urlQueryToSearchParams(url.query);\n result = appendSearchParamsToUrl(result, params);\n }\n return result;\n}\n\n/**\n * When `as` is provided, use it as the navigation target. This is a\n * simplification: Next.js keeps `url` and `as` as separate values (url for\n * data fetching, as for the browser URL). We collapse them because vinext's\n * navigateClient() fetches HTML from the target URL, so `as` must be a\n * server-resolvable path. Purely decorative `as` values are not supported.\n */\nfunction resolveNavigationTarget(\n url: string | UrlObject,\n as: string | undefined,\n locale: string | undefined,\n): string {\n return applyNavigationLocale(as ?? resolveUrl(url), locale);\n}\n\nfunction getDomainLocales(): readonly DomainLocale[] | undefined {\n return (window.__NEXT_DATA__ as VinextNextData | undefined)?.domainLocales;\n}\n\nfunction getCurrentHostname(): string | undefined {\n return window.location?.hostname;\n}\n\nfunction getDomainLocalePath(url: string, locale: string): string | undefined {\n return getDomainLocaleUrl(url, locale, {\n basePath: __basePath,\n currentHostname: getCurrentHostname(),\n domainItems: getDomainLocales(),\n });\n}\n\n/**\n * Apply locale prefix to a URL for client-side navigation.\n * Same logic as Link's applyLocaleToHref but reads from window globals.\n */\nexport function applyNavigationLocale(url: string, locale?: string): string {\n if (!locale || typeof window === \"undefined\") return url;\n // Absolute and protocol-relative URLs must not be prefixed — locale\n // only applies to local paths.\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\") || url.startsWith(\"//\")) {\n return url;\n }\n\n const domainLocalePath = getDomainLocalePath(url, locale);\n if (domainLocalePath) return domainLocalePath;\n\n return addLocalePrefix(url, locale, window.__VINEXT_DEFAULT_LOCALE__ ?? \"\");\n}\n\n/** Check if a URL is external (any URL scheme per RFC 3986, or protocol-relative) */\nexport function isExternalUrl(url: string): boolean {\n return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith(\"//\");\n}\n\n/** Resolve a hash URL to a basePath-stripped app URL for event payloads */\nfunction resolveHashUrl(url: string): string {\n if (typeof window === \"undefined\") return url;\n if (url.startsWith(\"#\"))\n return stripBasePath(window.location.pathname, __basePath) + window.location.search + url;\n // Full-path hash URL — strip basePath for consistency with other events\n try {\n const parsed = new URL(url, window.location.href);\n return stripBasePath(parsed.pathname, __basePath) + parsed.search + parsed.hash;\n } catch {\n return url;\n }\n}\n\n/** Check if a href is only a hash change relative to the current URL */\nexport function isHashOnlyChange(href: string): boolean {\n if (href.startsWith(\"#\")) return true;\n if (typeof window === \"undefined\") return false;\n return isHashOnlyBrowserUrlChange(href, window.location.href, __basePath);\n}\n\n/** Scroll to hash target element, or top if no hash */\nfunction scrollToHash(hash: string): void {\n if (!hash || hash === \"#\") {\n window.scrollTo(0, 0);\n return;\n }\n const el = document.getElementById(hash.slice(1));\n if (el) el.scrollIntoView({ behavior: \"auto\" });\n}\n\n/** Save current scroll position into history state for back/forward restoration */\nfunction saveScrollPosition(): void {\n const state = window.history.state ?? {};\n window.history.replaceState(\n { ...state, __vinext_scrollX: window.scrollX, __vinext_scrollY: window.scrollY },\n \"\",\n );\n}\n\n/** Restore scroll position from history state */\nfunction restoreScrollPosition(state: unknown): void {\n if (state && typeof state === \"object\" && \"__vinext_scrollY\" in state) {\n const { __vinext_scrollX: x, __vinext_scrollY: y } = state as {\n __vinext_scrollX: number;\n __vinext_scrollY: number;\n };\n requestAnimationFrame(() => window.scrollTo(x, y));\n }\n}\n\n/**\n * SSR context - set by the dev server before rendering each page.\n */\ntype SSRContext = {\n pathname: string;\n query: Record<string, string | string[]>;\n asPath: string;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n domainLocales?: VinextNextData[\"domainLocales\"];\n};\n\n// ---------------------------------------------------------------------------\n// Server-side SSR state uses a registration pattern so this module can be\n// bundled for the browser. The ALS-backed implementation lives in\n// router-state.ts (server-only) and registers itself on import.\n// ---------------------------------------------------------------------------\n\nlet _ssrContext: SSRContext | null = null;\n\nlet _getSSRContext = (): SSRContext | null => _ssrContext;\nlet _setSSRContextImpl = (ctx: SSRContext | null): void => {\n _ssrContext = ctx;\n};\n\n/**\n * Register ALS-backed state accessors. Called by router-state.ts on import.\n * @internal\n */\nexport function _registerRouterStateAccessors(accessors: {\n getSSRContext: () => SSRContext | null;\n setSSRContext: (ctx: SSRContext | null) => void;\n}): void {\n _getSSRContext = accessors.getSSRContext;\n _setSSRContextImpl = accessors.setSSRContext;\n}\n\nexport function setSSRContext(ctx: SSRContext | null): void {\n _setSSRContextImpl(ctx);\n}\n\n/**\n * Extract param names from a Next.js route pattern.\n * E.g., \"/posts/[id]\" → [\"id\"], \"/docs/[...slug]\" → [\"slug\"],\n * \"/shop/[[...path]]\" → [\"path\"], \"/blog/[year]/[month]\" → [\"year\", \"month\"]\n * Also handles internal format: \"/posts/:id\" → [\"id\"], \"/docs/:slug+\" → [\"slug\"]\n */\nfunction extractRouteParamNames(pattern: string): string[] {\n const names: string[] = [];\n // Match Next.js bracket format: [id], [...slug], [[...slug]]\n // Accepts any non-] characters inside brackets (Next.js PARAMETER_PATTERN parity).\n const bracketMatches = pattern.matchAll(/\\[{1,2}(?:\\.\\.\\.)?([^\\]]+)\\]{1,2}/g);\n for (const m of bracketMatches) {\n names.push(m[1]);\n }\n if (names.length > 0) return names;\n // Fallback: match internal :param format (any chars except /, +, *)\n const colonMatches = pattern.matchAll(/:([^/+*]+)[+*]?/g);\n for (const m of colonMatches) {\n names.push(m[1]);\n }\n return names;\n}\n\nfunction getPathnameAndQuery(): {\n pathname: string;\n query: Record<string, string | string[]>;\n asPath: string;\n} {\n if (typeof window === \"undefined\") {\n const _ssrCtx = _getSSRContext();\n if (_ssrCtx) {\n const query: Record<string, string | string[]> = {};\n for (const [key, value] of Object.entries(_ssrCtx.query)) {\n query[key] = Array.isArray(value) ? [...value] : value;\n }\n return { pathname: _ssrCtx.pathname, query, asPath: _ssrCtx.asPath };\n }\n return { pathname: \"/\", query: {}, asPath: \"/\" };\n }\n const resolvedPath = stripBasePath(window.location.pathname, __basePath);\n // In Next.js, router.pathname is the route pattern (e.g., \"/posts/[id]\"),\n // not the resolved path (\"/posts/42\"). __NEXT_DATA__.page holds the route\n // pattern and is updated by navigateClient() on every client-side navigation.\n const pathname = window.__NEXT_DATA__?.page ?? resolvedPath;\n const routeQuery: Record<string, string | string[]> = {};\n // Include dynamic route params from __NEXT_DATA__ (e.g., { id: \"42\" } from /posts/[id]).\n // Only include keys that are part of the route pattern (not stale query params).\n const nextData = window.__NEXT_DATA__;\n if (nextData && nextData.query && nextData.page) {\n const routeParamNames = extractRouteParamNames(nextData.page);\n for (const key of routeParamNames) {\n const value = nextData.query[key];\n if (typeof value === \"string\") {\n routeQuery[key] = value;\n } else if (Array.isArray(value)) {\n routeQuery[key] = [...value];\n }\n }\n }\n // URL search params always reflect the current URL\n const searchQuery: Record<string, string | string[]> = {};\n const params = new URLSearchParams(window.location.search);\n for (const [key, value] of params) {\n addQueryParam(searchQuery, key, value);\n }\n const query = { ...searchQuery, ...routeQuery };\n // asPath uses the resolved browser path, not the route pattern\n const asPath = resolvedPath + window.location.search + window.location.hash;\n return { pathname, query, asPath };\n}\n\n/**\n * Error thrown when a navigation is superseded by a newer one.\n * Matches Next.js's convention of an Error with `.cancelled = true`.\n */\nclass NavigationCancelledError extends Error {\n cancelled = true;\n constructor(route: string) {\n super(`Abort fetching component for route: \"${route}\"`);\n this.name = \"NavigationCancelledError\";\n }\n}\n\n/**\n * Error thrown after queueing a hard navigation fallback for a known failure\n * mode. Callers can use this to avoid scheduling the same hard navigation twice.\n */\nclass HardNavigationScheduledError extends Error {\n hardNavigationScheduled = true;\n constructor(message: string) {\n super(message);\n this.name = \"HardNavigationScheduledError\";\n }\n}\n\n/**\n * Monotonically increasing ID for tracking the current navigation.\n * Each call to navigateClient() increments this and captures the value.\n * After each async boundary, the navigation checks whether it is still\n * the active one. If a newer navigation has started, the stale one\n * throws NavigationCancelledError so the caller can emit routeChangeError\n * and skip routeChangeComplete.\n *\n * Replaces the old boolean `_navInProgress` guard which silently dropped\n * the second navigation, causing URL/content mismatch.\n */\nlet _navigationId = 0;\n\n/** AbortController for the in-flight fetch, so superseded navigations abort network I/O. */\nlet _activeAbortController: AbortController | null = null;\n\nfunction scheduleHardNavigationAndThrow(url: string, message: string): never {\n if (typeof window === \"undefined\") {\n throw new HardNavigationScheduledError(message);\n }\n window.location.href = url;\n throw new HardNavigationScheduledError(message);\n}\n\n/**\n * Perform client-side navigation: fetch the target page's HTML,\n * extract __NEXT_DATA__, and re-render the React root.\n *\n * Throws NavigationCancelledError if a newer navigation supersedes this one.\n * Throws on hard-navigation failures (non-OK response, missing data) so the\n * caller can distinguish success from failure for event emission.\n */\nasync function navigateClient(url: string): Promise<void> {\n if (typeof window === \"undefined\") return;\n\n const root = window.__VINEXT_ROOT__;\n if (!root) {\n // No React root yet — fall back to hard navigation\n window.location.href = url;\n return;\n }\n\n // Cancel any in-flight navigation (abort its fetch, mark it stale)\n _activeAbortController?.abort();\n const controller = new AbortController();\n _activeAbortController = controller;\n\n const navId = ++_navigationId;\n\n /** Check if this navigation is still the active one. If not, throw. */\n function assertStillCurrent(): void {\n if (navId !== _navigationId) {\n throw new NavigationCancelledError(url);\n }\n }\n\n try {\n // Fetch the target page's SSR HTML\n let res: Response;\n try {\n res = await fetch(url, {\n headers: { Accept: \"text/html\" },\n signal: controller.signal,\n });\n } catch (err: unknown) {\n // AbortError means a newer navigation cancelled this fetch\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new NavigationCancelledError(url);\n }\n throw err;\n }\n assertStillCurrent();\n\n if (!res.ok) {\n // Set window.location.href first so the browser navigates to the correct\n // page even if the caller suppresses the error. The assignment schedules\n // the navigation asynchronously (as a task), so synchronous routeChangeError\n // listeners still run — and observe the error — before the page unloads.\n // Contract: routeChangeError listeners MUST be synchronous; async listeners\n // will not fire before the navigation completes. Callers (runNavigateClient)\n // must NOT schedule a second hard navigation — this assignment already queues\n // the browser fallback, and the helper-level HardNavigationScheduledError\n // makes that contract explicit to callers.\n scheduleHardNavigationAndThrow(url, `Navigation failed: ${res.status} ${res.statusText}`);\n }\n\n const html = await res.text();\n assertStillCurrent();\n\n // Extract __NEXT_DATA__ from the HTML\n const match = html.match(/<script>window\\.__NEXT_DATA__\\s*=\\s*(.*?)<\\/script>/);\n if (!match) {\n scheduleHardNavigationAndThrow(url, \"Navigation failed: missing __NEXT_DATA__ in response\");\n }\n\n const nextData = JSON.parse(match[1]);\n const { pageProps } = nextData.props;\n // Defer writing window.__NEXT_DATA__ until just before root.render() —\n // writing it here would let a stale navigation briefly pollute the global\n // between this assertStillCurrent() and the next one after await import().\n\n // Get the page module URL from __NEXT_DATA__.__vinext (preferred),\n // or fall back to parsing the hydration script\n let pageModuleUrl: string | undefined = nextData.__vinext?.pageModuleUrl;\n\n if (!pageModuleUrl) {\n // Legacy fallback: try to find the module URL in the inline script\n const moduleMatch = html.match(/import\\(\"([^\"]+)\"\\);\\s*\\n\\s*const PageComponent/);\n const altMatch = html.match(/await import\\(\"([^\"]+pages\\/[^\"]+)\"\\)/);\n pageModuleUrl = moduleMatch?.[1] ?? altMatch?.[1] ?? undefined;\n }\n\n if (!pageModuleUrl) {\n scheduleHardNavigationAndThrow(url, \"Navigation failed: no page module URL found\");\n }\n\n // Validate the module URL before importing — defense-in-depth against\n // unexpected __NEXT_DATA__ or malformed HTML responses\n if (!isValidModulePath(pageModuleUrl)) {\n console.error(\"[vinext] Blocked import of invalid page module path:\", pageModuleUrl);\n scheduleHardNavigationAndThrow(url, \"Navigation failed: invalid page module path\");\n }\n\n // Dynamically import the new page module\n const pageModule = await import(/* @vite-ignore */ pageModuleUrl);\n assertStillCurrent();\n\n const PageComponent = pageModule.default;\n\n if (!PageComponent) {\n scheduleHardNavigationAndThrow(url, \"Navigation failed: page module has no default export\");\n }\n\n // Import React for createElement\n const React = (await import(\"react\")).default;\n assertStillCurrent();\n\n // Re-render with the new page, loading _app if needed\n let AppComponent = window.__VINEXT_APP__;\n const appModuleUrl: string | undefined = nextData.__vinext?.appModuleUrl;\n\n if (!AppComponent && appModuleUrl) {\n if (!isValidModulePath(appModuleUrl)) {\n console.error(\"[vinext] Blocked import of invalid app module path:\", appModuleUrl);\n } else {\n try {\n const appModule = await import(/* @vite-ignore */ appModuleUrl);\n AppComponent = appModule.default;\n window.__VINEXT_APP__ = AppComponent;\n } catch {\n // _app not available — continue without it\n }\n }\n }\n assertStillCurrent();\n\n let element;\n if (AppComponent) {\n element = React.createElement(AppComponent, {\n Component: PageComponent,\n pageProps,\n });\n } else {\n element = React.createElement(PageComponent, pageProps);\n }\n\n // Wrap with RouterContext.Provider so next/compat/router works\n element = wrapWithRouterContext(element);\n\n // Commit __NEXT_DATA__ only after all assertStillCurrent() checks have passed,\n // so a stale navigation can never pollute the global.\n // INVARIANT: Everything after the final assertStillCurrent() above (the\n // checkpoint immediately after the optional _app import) through\n // root.render() is synchronous. If any step here ever becomes async, add\n // another assertStillCurrent() before writing __NEXT_DATA__.\n window.__NEXT_DATA__ = nextData;\n root.render(element);\n } finally {\n // Clean up the abort controller if this navigation is still the active one\n if (navId === _navigationId) {\n _activeAbortController = null;\n }\n }\n}\n\n/**\n * Run navigateClient and handle errors: emit routeChangeError on failure,\n * and fall back to a hard navigation for non-cancel errors so the browser\n * recovers to a consistent state.\n *\n * Returns:\n * - \"completed\" — navigation finished, caller should emit routeChangeComplete\n * - \"cancelled\" — superseded by a newer navigation, caller should return true\n * without emitting routeChangeComplete (matches Next.js behaviour)\n * - \"failed\" — genuine error, caller should return false (hard nav is already\n * scheduled as recovery)\n */\nasync function runNavigateClient(\n fullUrl: string,\n resolvedUrl: string,\n): Promise<\"completed\" | \"cancelled\" | \"failed\"> {\n try {\n await navigateClient(fullUrl);\n return \"completed\";\n } catch (err: unknown) {\n routerEvents.emit(\"routeChangeError\", err, resolvedUrl, { shallow: false });\n if (err instanceof NavigationCancelledError) {\n return \"cancelled\";\n }\n // Genuine error (network, parse, import failure): fall back to a hard\n // navigation so the browser lands on the correct page. Known failure modes\n // throw HardNavigationScheduledError, and this guard skips those; only\n // unexpected failures (parse, import, render) need recovery here.\n if (typeof window !== \"undefined\" && !(err instanceof HardNavigationScheduledError)) {\n window.location.href = fullUrl;\n }\n return \"failed\";\n }\n}\n\n/**\n * Build the full router value object from the current pathname, query, asPath,\n * and a set of navigation methods. Shared by useRouter() (which passes\n * hook-derived callbacks) and wrapWithRouterContext() (which passes the Router\n * singleton methods) so the shape stays in sync.\n */\nfunction buildRouterValue(\n pathname: string,\n query: Record<string, string | string[]>,\n asPath: string,\n methods: {\n push: NextRouter[\"push\"];\n replace: NextRouter[\"replace\"];\n back: NextRouter[\"back\"];\n reload: NextRouter[\"reload\"];\n prefetch: NextRouter[\"prefetch\"];\n beforePopState: NextRouter[\"beforePopState\"];\n },\n): NextRouter {\n const _ssrState = _getSSRContext();\n const nextData =\n typeof window !== \"undefined\"\n ? (window.__NEXT_DATA__ as VinextNextData | undefined)\n : undefined;\n const locale = typeof window === \"undefined\" ? _ssrState?.locale : window.__VINEXT_LOCALE__;\n const locales = typeof window === \"undefined\" ? _ssrState?.locales : window.__VINEXT_LOCALES__;\n const defaultLocale =\n typeof window === \"undefined\" ? _ssrState?.defaultLocale : window.__VINEXT_DEFAULT_LOCALE__;\n const domainLocales =\n typeof window === \"undefined\" ? _ssrState?.domainLocales : nextData?.domainLocales;\n\n const route = typeof window !== \"undefined\" ? (nextData?.page ?? pathname) : pathname;\n\n return {\n pathname,\n route,\n query,\n asPath,\n basePath: __basePath,\n locale,\n locales,\n defaultLocale,\n domainLocales,\n isReady: true,\n isPreview: false,\n isFallback: typeof window !== \"undefined\" && nextData?.isFallback === true,\n ...methods,\n events: routerEvents,\n };\n}\n\n/**\n * useRouter hook - Pages Router compatible.\n */\nexport function useRouter(): NextRouter {\n const [{ pathname, query, asPath }, setState] = useState(getPathnameAndQuery);\n\n // Popstate is handled by the module-level listener below so beforePopState()\n // is consistently enforced even when multiple components mount useRouter().\n useEffect(() => {\n const onNavigate = ((_e: CustomEvent) => {\n setState(getPathnameAndQuery());\n }) as EventListener;\n window.addEventListener(\"vinext:navigate\", onNavigate);\n return () => window.removeEventListener(\"vinext:navigate\", onNavigate);\n }, []);\n\n const push = useCallback(\n async (url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean> => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs — delegate to browser (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.assign(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change — no page fetch needed\n if (isHashOnlyChange(full)) {\n const eventUrl = resolveHashUrl(full);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.pushState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n setState(getPathnameAndQuery());\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n saveScrollPosition();\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.pushState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n setState(getPathnameAndQuery());\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n // Scroll: handle hash target, else scroll to top unless scroll:false\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n [],\n );\n\n const replace = useCallback(\n async (url: string | UrlObject, as?: string, options?: TransitionOptions): Promise<boolean> => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs — delegate to browser (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.replace(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change — no page fetch needed\n if (isHashOnlyChange(full)) {\n const eventUrl = resolveHashUrl(full);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.replaceState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n setState(getPathnameAndQuery());\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.replaceState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n setState(getPathnameAndQuery());\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n // Scroll: handle hash target, else scroll to top unless scroll:false\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n [],\n );\n\n const back = useCallback(() => {\n window.history.back();\n }, []);\n\n const reload = useCallback(() => {\n window.location.reload();\n }, []);\n\n const prefetch = useCallback(async (url: string): Promise<void> => {\n // Inject a <link rel=\"prefetch\"> for the target page\n if (typeof document !== \"undefined\") {\n const link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = url;\n link.as = \"document\";\n document.head.appendChild(link);\n }\n }, []);\n\n const router = useMemo(\n (): NextRouter =>\n buildRouterValue(pathname, query, asPath, {\n push,\n replace,\n back,\n reload,\n prefetch,\n beforePopState: (cb: BeforePopStateCallback) => {\n _beforePopStateCb = cb;\n },\n }),\n [pathname, query, asPath, push, replace, back, reload, prefetch],\n );\n\n return router;\n}\n\n// beforePopState callback: called before handling browser back/forward.\n// If it returns false, the navigation is cancelled.\nlet _beforePopStateCb: BeforePopStateCallback | undefined;\n\n// Track pathname+search for detecting hash-only back/forward in the popstate\n// handler. Updated after every pushState/replaceState so that popstate can\n// compare the previous value with the (already-changed) window.location.\nlet _lastPathnameAndSearch =\n typeof window !== \"undefined\" ? window.location.pathname + window.location.search : \"\";\n\n// Module-level popstate listener: handles browser back/forward by re-rendering\n// the React root with the page at the new URL. This runs regardless of whether\n// any component calls useRouter().\nif (typeof window !== \"undefined\") {\n window.addEventListener(\"popstate\", (e: PopStateEvent) => {\n const browserUrl = window.location.pathname + window.location.search;\n const appUrl = stripBasePath(window.location.pathname, __basePath) + window.location.search;\n\n // Detect hash-only back/forward: pathname+search unchanged, only hash differs.\n const isHashOnly = browserUrl === _lastPathnameAndSearch;\n\n // Check beforePopState callback\n if (_beforePopStateCb !== undefined) {\n const shouldContinue = (_beforePopStateCb as BeforePopStateCallback)({\n url: appUrl,\n as: appUrl,\n options: { shallow: false },\n });\n if (!shouldContinue) return;\n }\n\n // Update tracker only after beforePopState confirms navigation proceeds.\n // If beforePopState cancels, the tracker must retain the previous value\n // so the next popstate compares against the correct baseline.\n _lastPathnameAndSearch = browserUrl;\n\n if (isHashOnly) {\n // Hash-only back/forward — no page fetch needed\n const hashUrl = appUrl + window.location.hash;\n routerEvents.emit(\"hashChangeStart\", hashUrl, { shallow: false });\n scrollToHash(window.location.hash);\n routerEvents.emit(\"hashChangeComplete\", hashUrl, { shallow: false });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return;\n }\n\n const fullAppUrl = appUrl + window.location.hash;\n routerEvents.emit(\"routeChangeStart\", fullAppUrl, { shallow: false });\n // Note: The browser has already updated window.location by the time popstate\n // fires, so this is not truly \"before\" the URL change. In Next.js the popstate\n // handler calls replaceState to store history metadata — beforeHistoryChange\n // precedes that call, not the URL change itself. We emit it here for API\n // compatibility.\n routerEvents.emit(\"beforeHistoryChange\", fullAppUrl, { shallow: false });\n void (async () => {\n const result = await runNavigateClient(browserUrl, fullAppUrl);\n if (result === \"completed\") {\n routerEvents.emit(\"routeChangeComplete\", fullAppUrl, { shallow: false });\n restoreScrollPosition(e.state);\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n }\n // \"cancelled\": superseded by a newer navigation, so this popstate no longer wins.\n // \"failed\": runNavigateClient already scheduled the hard-navigation fallback.\n })();\n });\n}\n\n/**\n * Wrap a React element in a RouterContext.Provider so that\n * next/compat/router's useRouter() returns the real Pages Router value.\n *\n * This is a plain function, NOT a React component — it builds the router\n * value object directly from the current SSR context (server) or\n * window.location + Router singleton (client), avoiding duplicate state\n * that a hook-based component would create.\n */\nexport function wrapWithRouterContext(element: ReactElement): ReactElement {\n const { pathname, query, asPath } = getPathnameAndQuery();\n\n const routerValue = buildRouterValue(pathname, query, asPath, {\n push: Router.push,\n replace: Router.replace,\n back: Router.back,\n reload: Router.reload,\n prefetch: Router.prefetch,\n beforePopState: Router.beforePopState,\n });\n\n return createElement(RouterContext.Provider, { value: routerValue }, element) as ReactElement;\n}\n\n/**\n * Props injected by `withRouter` into the wrapped component.\n *\n * Ported from Next.js: packages/next/src/client/with-router.tsx\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/with-router.tsx\n */\nexport type WithRouterProps = {\n router: NextRouter;\n};\n\n/**\n * Pick<P, Exclude<keyof P, keyof WithRouterProps>> — the props of the\n * composed component minus the `router` prop that `withRouter` injects.\n *\n * Ported from Next.js: packages/next/src/client/with-router.tsx\n */\nexport type ExcludeRouterProps<P> = Pick<P, Exclude<keyof P, keyof WithRouterProps>>;\n\n/**\n * Higher-order component that injects the Pages Router `router` instance as\n * a `router` prop into a wrapped component. Primarily used by class\n * components (which cannot call hooks) to access the router. The wrapped\n * component receives the same props as the original, minus `router`, which\n * is filled in by the HOC.\n *\n * Ported from Next.js: packages/next/src/client/with-router.tsx\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/client/with-router.tsx\n *\n * Differences from Next.js:\n * - We type the composed component as `ComponentType<P>` instead of\n * `NextComponentType<C, any, P>` because vinext does not expose\n * `NextComponentType` from this shim. The runtime shape (and the props\n * the wrapper forwards) is identical.\n * - We forward `getInitialProps` and `origGetInitialProps` from the\n * composed component so `_app` parity holds for class components that\n * define `getInitialProps`.\n */\nexport function withRouter<P extends WithRouterProps>(\n ComposedComponent: ComponentType<P>,\n): ComponentType<ExcludeRouterProps<P>> {\n function WithRouterWrapper(props: ExcludeRouterProps<P>): ReactElement {\n const router = useRouter();\n // Match Next.js spread order:\n // `<ComposedComponent router={useRouter()} {...props} />`\n // The injected `router` is placed first, and `{...props}` is spread\n // after, so a user-passed `router` prop overrides the HOC-injected\n // one (last-spread wins). Mirrors\n // packages/next/src/client/with-router.tsx. At the type level\n // `props: ExcludeRouterProps<P>` has no `router` key, but TS still\n // sees `P` as `WithRouterProps`-extending when checking the literal,\n // so we widen to a `Record` for the final prop bag.\n const merged: Record<string, unknown> = { router, ...(props as Record<string, unknown>) };\n return createElement(ComposedComponent, merged as unknown as P);\n }\n\n // Forward getInitialProps so class-component pages that define it keep\n // working when wrapped. Mirrors Next.js's with-router.tsx.\n const composed = ComposedComponent as ComponentType<P> & {\n getInitialProps?: unknown;\n origGetInitialProps?: unknown;\n };\n (WithRouterWrapper as unknown as { getInitialProps?: unknown }).getInitialProps =\n composed.getInitialProps;\n (WithRouterWrapper as unknown as { origGetInitialProps?: unknown }).origGetInitialProps =\n composed.origGetInitialProps;\n\n if (process.env.NODE_ENV !== \"production\") {\n const name = composed.displayName || composed.name || \"Unknown\";\n WithRouterWrapper.displayName = `withRouter(${name})`;\n }\n\n return WithRouterWrapper;\n}\n\n// Note: `withRouter` is exposed only as a named export from `next/router`.\n// The default export of that module is the Router singleton declared below.\n\n// Also export a default Router singleton for `import Router from 'next/router'`\nconst Router = {\n push: async (url: string | UrlObject, as?: string, options?: TransitionOptions) => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.assign(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change\n if (isHashOnlyChange(full)) {\n const eventUrl = resolveHashUrl(full);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.pushState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n saveScrollPosition();\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.pushState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n replace: async (url: string | UrlObject, as?: string, options?: TransitionOptions) => {\n let resolved = resolveNavigationTarget(url, as, options?.locale);\n\n // External URLs (unless same-origin)\n if (isExternalUrl(resolved)) {\n const localPath = toSameOriginAppPath(resolved, __basePath);\n if (localPath == null) {\n window.location.replace(resolved);\n return true;\n }\n resolved = localPath;\n }\n\n const full = toBrowserNavigationHref(resolved, window.location.href, __basePath);\n\n // Hash-only change\n if (isHashOnlyChange(full)) {\n const eventUrl = resolveHashUrl(full);\n routerEvents.emit(\"hashChangeStart\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n window.history.replaceState({}, \"\", resolved.startsWith(\"#\") ? resolved : full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n scrollToHash(hash);\n routerEvents.emit(\"hashChangeComplete\", eventUrl, {\n shallow: options?.shallow ?? false,\n });\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n }\n\n routerEvents.emit(\"routeChangeStart\", resolved, { shallow: options?.shallow ?? false });\n routerEvents.emit(\"beforeHistoryChange\", resolved, { shallow: options?.shallow ?? false });\n window.history.replaceState({}, \"\", full);\n _lastPathnameAndSearch = window.location.pathname + window.location.search;\n if (!options?.shallow) {\n const result = await runNavigateClient(full, resolved);\n if (result === \"cancelled\") return true;\n if (result === \"failed\") return false;\n }\n routerEvents.emit(\"routeChangeComplete\", resolved, { shallow: options?.shallow ?? false });\n\n const hash = resolved.includes(\"#\") ? resolved.slice(resolved.indexOf(\"#\")) : \"\";\n if (hash) {\n scrollToHash(hash);\n } else if (options?.scroll !== false) {\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new CustomEvent(\"vinext:navigate\"));\n return true;\n },\n back: () => window.history.back(),\n reload: () => window.location.reload(),\n prefetch: async (url: string) => {\n if (typeof document !== \"undefined\") {\n const link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = url;\n link.as = \"document\";\n document.head.appendChild(link);\n }\n },\n beforePopState: (cb: BeforePopStateCallback) => {\n _beforePopStateCb = cb;\n },\n events: routerEvents,\n};\n\n// Expose `window.next.router` for Next.js parity. Pages Router test suites,\n// userland scripts, and third-party libraries reach for this global directly\n// (e.g. `window.next.router.push(...)`, `window.next.router.events.on(...)`).\n// Without this assignment, those callers crash with\n// `TypeError: Cannot read properties of undefined (reading 'router')`.\n//\n// Ported from Next.js: `packages/next/src/client/next.ts` (line 13). We do\n// NOT use a live-binding getter like Next.js does because vinext's Router\n// singleton is constructed synchronously here, so by the time this module\n// finishes loading the value is final.\nif (typeof window !== \"undefined\") {\n // Cast: `NextRouter.push`/`replace` are typed with narrow parameters\n // (UrlObject | string) while `PagesRouterPublicInstance` accepts unknown\n // args. The two are structurally compatible at runtime; TypeScript flags\n // the narrowing of contravariant function params, which is benign here\n // because callers reading off `window.next.router` are tests/userland\n // and treat the surface as opaque.\n installWindowNext({ router: Router as unknown as PagesRouterPublicInstance });\n}\n\nexport default Router;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-nonce-context.js","names":[],"sources":["../../src/shims/script-nonce-context.tsx"],"sourcesContent":["import React from \"react\";\n\nexport const ScriptNonceContext = React.createContext<string | undefined>(undefined);\n\nexport function ScriptNonceProvider(\n props: React.PropsWithChildren<{\n nonce?: string;\n }>,\n): React.ReactElement {\n return React.createElement(ScriptNonceContext.Provider, { value: props.nonce }, props.children);\n}\n\nexport function withScriptNonce(element: React.ReactElement, nonce?: string): React.ReactElement {\n if (!nonce) {\n return element;\n }\n\n return React.createElement(ScriptNonceProvider, { nonce }, element);\n}\n\nexport function useScriptNonce(): string | undefined {\n return React.useContext(ScriptNonceContext);\n}\n"],"mappings":";;AAEA,MAAa,qBAAqB,MAAM,cAAkC,KAAA,EAAU;AAEpF,SAAgB,oBACd,OAGoB;
|
|
1
|
+
{"version":3,"file":"script-nonce-context.js","names":[],"sources":["../../src/shims/script-nonce-context.tsx"],"sourcesContent":["import React from \"react\";\n\nexport const ScriptNonceContext = React.createContext<string | undefined>(undefined);\n\nexport function ScriptNonceProvider(\n props: React.PropsWithChildren<{\n nonce?: string;\n }>,\n): React.ReactElement {\n return React.createElement(ScriptNonceContext.Provider, { value: props.nonce }, props.children);\n}\n\nexport function withScriptNonce(element: React.ReactElement, nonce?: string): React.ReactElement {\n if (!nonce) {\n return element;\n }\n\n return React.createElement(ScriptNonceProvider, { nonce }, element);\n}\n\nexport function useScriptNonce(): string | undefined {\n return React.useContext(ScriptNonceContext);\n}\n"],"mappings":";;AAEA,MAAa,qBAAqB,MAAM,cAAkC,KAAA,EAAU;AAEpF,SAAgB,oBACd,OAGoB;CACpB,OAAO,MAAM,cAAc,mBAAmB,UAAU,EAAE,OAAO,MAAM,OAAO,EAAE,MAAM,SAAS;;AAGjG,SAAgB,gBAAgB,SAA6B,OAAoC;CAC/F,IAAI,CAAC,OACH,OAAO;CAGT,OAAO,MAAM,cAAc,qBAAqB,EAAE,OAAO,EAAE,QAAQ;;AAGrE,SAAgB,iBAAqC;CACnD,OAAO,MAAM,WAAW,mBAAmB"}
|
package/dist/shims/script.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script.js","names":[],"sources":["../../src/shims/script.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * next/script shim\n *\n * Provides the <Script> component for loading third-party scripts with\n * configurable loading strategies.\n *\n * Strategies:\n * - \"beforeInteractive\": rendered as a <script> tag in SSR output\n * - \"afterInteractive\" (default): loaded client-side after hydration\n * - \"lazyOnload\": deferred until window.load + requestIdleCallback\n * - \"worker\": sets type=\"text/partytown\" (requires Partytown setup)\n */\nimport React, { useEffect, useRef } from \"react\";\nimport { escapeInlineContent } from \"./head.js\";\nimport { useScriptNonce } from \"./script-nonce-context.js\";\n\nexport type ScriptProps = {\n /** Script source URL */\n src?: string;\n /** Loading strategy. Default: \"afterInteractive\" */\n strategy?: \"beforeInteractive\" | \"afterInteractive\" | \"lazyOnload\" | \"worker\";\n /** Unique identifier for the script */\n id?: string;\n /** Called when the script has loaded */\n onLoad?: (e: Event) => void;\n /** Called when the script is ready (after load, and on every re-render if already loaded) */\n onReady?: () => void;\n /** Called on script load error */\n onError?: (e: Event) => void;\n /** Inline script content */\n children?: React.ReactNode;\n /** Dangerous inner HTML */\n dangerouslySetInnerHTML?: { __html: string };\n /** Script type attribute */\n type?: string;\n /** Async attribute */\n async?: boolean;\n /** Defer attribute */\n defer?: boolean;\n /** Crossorigin attribute */\n crossOrigin?: string;\n /** Nonce for CSP */\n nonce?: string;\n /** Integrity hash */\n integrity?: string;\n /** Additional attributes */\n [key: string]: unknown;\n};\n\n// Track scripts that have already been loaded to avoid duplicates\nconst loadedScripts = new Set<string>();\n\nfunction getClientAutoNonce(): string | undefined {\n if (typeof document === \"undefined\") return undefined;\n\n const existingNonceElement = document.querySelector(\"[nonce]\");\n if (!(existingNonceElement instanceof HTMLElement)) {\n return undefined;\n }\n\n return existingNonceElement.nonce || existingNonceElement.getAttribute(\"nonce\") || undefined;\n}\n\nfunction resolveScriptNonce(explicitNonce: unknown, contextualNonce?: string): string | undefined {\n if (typeof explicitNonce === \"string\" && explicitNonce.length > 0) {\n return explicitNonce;\n }\n\n if (typeof window === \"undefined\") {\n return contextualNonce;\n }\n\n return getClientAutoNonce();\n}\n\nfunction buildBeforeInteractiveScriptProps(options: {\n src?: string;\n id?: string;\n rest: Record<string, unknown>;\n resolvedNonce?: string;\n dangerouslySetInnerHTML?: { __html: string };\n}): Record<string, unknown> {\n const scriptProps: Record<string, unknown> = { ...options.rest };\n if (options.src) scriptProps.src = options.src;\n if (options.id) scriptProps.id = options.id;\n if (options.resolvedNonce) {\n scriptProps.nonce = options.resolvedNonce;\n }\n if (options.dangerouslySetInnerHTML) {\n scriptProps.dangerouslySetInnerHTML = {\n __html: escapeInlineContent(options.dangerouslySetInnerHTML.__html, \"script\"),\n };\n }\n return scriptProps;\n}\n\n/**\n * Load a script imperatively (outside of React).\n */\nexport function handleClientScriptLoad(props: ScriptProps): void {\n const {\n src,\n id,\n onLoad,\n onError,\n strategy: _strategy,\n onReady: _onReady,\n children,\n ...rest\n } = props;\n if (typeof window === \"undefined\") return;\n\n const key = id ?? src ?? \"\";\n if (key && loadedScripts.has(key)) return;\n\n const el = document.createElement(\"script\");\n if (src) el.src = src;\n if (id) el.id = id;\n const resolvedNonce = resolveScriptNonce(rest.nonce);\n\n for (const [attr, value] of Object.entries(rest)) {\n if (attr === \"dangerouslySetInnerHTML\" || attr === \"className\") continue;\n if (typeof value === \"string\") {\n el.setAttribute(attr, value);\n } else if (typeof value === \"boolean\" && value) {\n el.setAttribute(attr, \"\");\n }\n }\n if (resolvedNonce && !el.getAttribute(\"nonce\")) {\n el.setAttribute(\"nonce\", resolvedNonce);\n }\n\n if (children && typeof children === \"string\") {\n el.textContent = children;\n }\n\n if (onLoad) el.addEventListener(\"load\", onLoad);\n if (onError) el.addEventListener(\"error\", onError);\n\n document.body.appendChild(el);\n if (key) loadedScripts.add(key);\n}\n\n/**\n * Initialize multiple scripts at once (called during app bootstrap).\n */\nexport function initScriptLoader(scripts: ScriptProps[]): void {\n for (const script of scripts) {\n handleClientScriptLoad(script);\n }\n}\n\nfunction Script(props: ScriptProps): React.ReactElement | null {\n const {\n src,\n id,\n strategy = \"afterInteractive\",\n onLoad,\n onReady,\n onError,\n children,\n dangerouslySetInnerHTML,\n ...rest\n } = props;\n\n const hasMounted = useRef(false);\n const key = id ?? src ?? \"\";\n const contextualNonce = useScriptNonce();\n const resolvedNonce = resolveScriptNonce(rest.nonce, contextualNonce);\n\n // Client path: load scripts via useEffect based on strategy.\n // useEffect never runs during SSR, so it's safe to call unconditionally.\n useEffect(() => {\n if (hasMounted.current) return;\n hasMounted.current = true;\n\n if (strategy === \"beforeInteractive\") {\n return;\n }\n\n // Already loaded — just fire onReady\n if (key && loadedScripts.has(key)) {\n onReady?.();\n return;\n }\n\n const load = () => {\n if (key && loadedScripts.has(key)) {\n onReady?.();\n return;\n }\n\n const el = document.createElement(\"script\");\n if (src) el.src = src;\n if (id) el.id = id;\n\n for (const [attr, value] of Object.entries(rest)) {\n if (attr === \"className\") {\n el.setAttribute(\"class\", String(value));\n } else if (typeof value === \"string\") {\n el.setAttribute(attr, value);\n } else if (typeof value === \"boolean\" && value) {\n el.setAttribute(attr, \"\");\n }\n }\n if (resolvedNonce && !el.getAttribute(\"nonce\")) {\n el.setAttribute(\"nonce\", resolvedNonce);\n }\n\n if (strategy === \"worker\") {\n el.setAttribute(\"type\", \"text/partytown\");\n }\n\n if (dangerouslySetInnerHTML?.__html) {\n // Intentional: mirrors the Next.js <Script> API where dangerouslySetInnerHTML\n // is developer-supplied inline script content (not user input). The prop name\n // itself signals developer awareness of the XSS risk, consistent with React's\n // design. User-supplied data must never flow into this prop.\n el.innerHTML = dangerouslySetInnerHTML.__html as string;\n } else if (children && typeof children === \"string\") {\n el.textContent = children;\n }\n\n el.addEventListener(\"load\", (e) => {\n if (key) loadedScripts.add(key);\n onLoad?.(e);\n onReady?.();\n });\n\n if (onError) {\n el.addEventListener(\"error\", onError);\n }\n\n document.body.appendChild(el);\n };\n\n if (strategy === \"lazyOnload\") {\n // Wait for window load, then use idle callback\n if (document.readyState === \"complete\") {\n if (typeof requestIdleCallback === \"function\") {\n requestIdleCallback(load);\n } else {\n setTimeout(load, 1);\n }\n } else {\n window.addEventListener(\"load\", () => {\n if (typeof requestIdleCallback === \"function\") {\n requestIdleCallback(load);\n } else {\n setTimeout(load, 1);\n }\n });\n }\n } else {\n // \"afterInteractive\" (default), \"beforeInteractive\" (client re-mount), \"worker\"\n load();\n }\n }, [\n src,\n id,\n strategy,\n onLoad,\n onReady,\n onError,\n children,\n dangerouslySetInnerHTML,\n key,\n resolvedNonce,\n rest,\n ]);\n\n // SSR path: only \"beforeInteractive\" renders a <script> tag server-side\n if (typeof window === \"undefined\") {\n if (strategy === \"beforeInteractive\") {\n return React.createElement(\n \"script\",\n buildBeforeInteractiveScriptProps({\n src,\n id,\n rest,\n resolvedNonce,\n dangerouslySetInnerHTML,\n }),\n children,\n );\n }\n // Other strategies don't render during SSR\n return null;\n }\n\n if (strategy === \"beforeInteractive\") {\n return React.createElement(\n \"script\",\n buildBeforeInteractiveScriptProps({\n src,\n id,\n rest,\n resolvedNonce,\n dangerouslySetInnerHTML,\n }),\n children,\n );\n }\n\n // The component itself renders nothing — scripts are injected imperatively\n return null;\n}\n\nexport default Script;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"script.js","names":[],"sources":["../../src/shims/script.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * next/script shim\n *\n * Provides the <Script> component for loading third-party scripts with\n * configurable loading strategies.\n *\n * Strategies:\n * - \"beforeInteractive\": rendered as a <script> tag in SSR output\n * - \"afterInteractive\" (default): loaded client-side after hydration\n * - \"lazyOnload\": deferred until window.load + requestIdleCallback\n * - \"worker\": sets type=\"text/partytown\" (requires Partytown setup)\n */\nimport React, { useEffect, useRef } from \"react\";\nimport { escapeInlineContent } from \"./head.js\";\nimport { useScriptNonce } from \"./script-nonce-context.js\";\n\nexport type ScriptProps = {\n /** Script source URL */\n src?: string;\n /** Loading strategy. Default: \"afterInteractive\" */\n strategy?: \"beforeInteractive\" | \"afterInteractive\" | \"lazyOnload\" | \"worker\";\n /** Unique identifier for the script */\n id?: string;\n /** Called when the script has loaded */\n onLoad?: (e: Event) => void;\n /** Called when the script is ready (after load, and on every re-render if already loaded) */\n onReady?: () => void;\n /** Called on script load error */\n onError?: (e: Event) => void;\n /** Inline script content */\n children?: React.ReactNode;\n /** Dangerous inner HTML */\n dangerouslySetInnerHTML?: { __html: string };\n /** Script type attribute */\n type?: string;\n /** Async attribute */\n async?: boolean;\n /** Defer attribute */\n defer?: boolean;\n /** Crossorigin attribute */\n crossOrigin?: string;\n /** Nonce for CSP */\n nonce?: string;\n /** Integrity hash */\n integrity?: string;\n /** Additional attributes */\n [key: string]: unknown;\n};\n\n// Track scripts that have already been loaded to avoid duplicates\nconst loadedScripts = new Set<string>();\n\nfunction getClientAutoNonce(): string | undefined {\n if (typeof document === \"undefined\") return undefined;\n\n const existingNonceElement = document.querySelector(\"[nonce]\");\n if (!(existingNonceElement instanceof HTMLElement)) {\n return undefined;\n }\n\n return existingNonceElement.nonce || existingNonceElement.getAttribute(\"nonce\") || undefined;\n}\n\nfunction resolveScriptNonce(explicitNonce: unknown, contextualNonce?: string): string | undefined {\n if (typeof explicitNonce === \"string\" && explicitNonce.length > 0) {\n return explicitNonce;\n }\n\n if (typeof window === \"undefined\") {\n return contextualNonce;\n }\n\n return getClientAutoNonce();\n}\n\nfunction buildBeforeInteractiveScriptProps(options: {\n src?: string;\n id?: string;\n rest: Record<string, unknown>;\n resolvedNonce?: string;\n dangerouslySetInnerHTML?: { __html: string };\n}): Record<string, unknown> {\n const scriptProps: Record<string, unknown> = { ...options.rest };\n if (options.src) scriptProps.src = options.src;\n if (options.id) scriptProps.id = options.id;\n if (options.resolvedNonce) {\n scriptProps.nonce = options.resolvedNonce;\n }\n if (options.dangerouslySetInnerHTML) {\n scriptProps.dangerouslySetInnerHTML = {\n __html: escapeInlineContent(options.dangerouslySetInnerHTML.__html, \"script\"),\n };\n }\n return scriptProps;\n}\n\n/**\n * Load a script imperatively (outside of React).\n */\nexport function handleClientScriptLoad(props: ScriptProps): void {\n const {\n src,\n id,\n onLoad,\n onError,\n strategy: _strategy,\n onReady: _onReady,\n children,\n ...rest\n } = props;\n if (typeof window === \"undefined\") return;\n\n const key = id ?? src ?? \"\";\n if (key && loadedScripts.has(key)) return;\n\n const el = document.createElement(\"script\");\n if (src) el.src = src;\n if (id) el.id = id;\n const resolvedNonce = resolveScriptNonce(rest.nonce);\n\n for (const [attr, value] of Object.entries(rest)) {\n if (attr === \"dangerouslySetInnerHTML\" || attr === \"className\") continue;\n if (typeof value === \"string\") {\n el.setAttribute(attr, value);\n } else if (typeof value === \"boolean\" && value) {\n el.setAttribute(attr, \"\");\n }\n }\n if (resolvedNonce && !el.getAttribute(\"nonce\")) {\n el.setAttribute(\"nonce\", resolvedNonce);\n }\n\n if (children && typeof children === \"string\") {\n el.textContent = children;\n }\n\n if (onLoad) el.addEventListener(\"load\", onLoad);\n if (onError) el.addEventListener(\"error\", onError);\n\n document.body.appendChild(el);\n if (key) loadedScripts.add(key);\n}\n\n/**\n * Initialize multiple scripts at once (called during app bootstrap).\n */\nexport function initScriptLoader(scripts: ScriptProps[]): void {\n for (const script of scripts) {\n handleClientScriptLoad(script);\n }\n}\n\nfunction Script(props: ScriptProps): React.ReactElement | null {\n const {\n src,\n id,\n strategy = \"afterInteractive\",\n onLoad,\n onReady,\n onError,\n children,\n dangerouslySetInnerHTML,\n ...rest\n } = props;\n\n const hasMounted = useRef(false);\n const key = id ?? src ?? \"\";\n const contextualNonce = useScriptNonce();\n const resolvedNonce = resolveScriptNonce(rest.nonce, contextualNonce);\n\n // Client path: load scripts via useEffect based on strategy.\n // useEffect never runs during SSR, so it's safe to call unconditionally.\n useEffect(() => {\n if (hasMounted.current) return;\n hasMounted.current = true;\n\n if (strategy === \"beforeInteractive\") {\n return;\n }\n\n // Already loaded — just fire onReady\n if (key && loadedScripts.has(key)) {\n onReady?.();\n return;\n }\n\n const load = () => {\n if (key && loadedScripts.has(key)) {\n onReady?.();\n return;\n }\n\n const el = document.createElement(\"script\");\n if (src) el.src = src;\n if (id) el.id = id;\n\n for (const [attr, value] of Object.entries(rest)) {\n if (attr === \"className\") {\n el.setAttribute(\"class\", String(value));\n } else if (typeof value === \"string\") {\n el.setAttribute(attr, value);\n } else if (typeof value === \"boolean\" && value) {\n el.setAttribute(attr, \"\");\n }\n }\n if (resolvedNonce && !el.getAttribute(\"nonce\")) {\n el.setAttribute(\"nonce\", resolvedNonce);\n }\n\n if (strategy === \"worker\") {\n el.setAttribute(\"type\", \"text/partytown\");\n }\n\n if (dangerouslySetInnerHTML?.__html) {\n // Intentional: mirrors the Next.js <Script> API where dangerouslySetInnerHTML\n // is developer-supplied inline script content (not user input). The prop name\n // itself signals developer awareness of the XSS risk, consistent with React's\n // design. User-supplied data must never flow into this prop.\n el.innerHTML = dangerouslySetInnerHTML.__html as string;\n } else if (children && typeof children === \"string\") {\n el.textContent = children;\n }\n\n el.addEventListener(\"load\", (e) => {\n if (key) loadedScripts.add(key);\n onLoad?.(e);\n onReady?.();\n });\n\n if (onError) {\n el.addEventListener(\"error\", onError);\n }\n\n document.body.appendChild(el);\n };\n\n if (strategy === \"lazyOnload\") {\n // Wait for window load, then use idle callback\n if (document.readyState === \"complete\") {\n if (typeof requestIdleCallback === \"function\") {\n requestIdleCallback(load);\n } else {\n setTimeout(load, 1);\n }\n } else {\n window.addEventListener(\"load\", () => {\n if (typeof requestIdleCallback === \"function\") {\n requestIdleCallback(load);\n } else {\n setTimeout(load, 1);\n }\n });\n }\n } else {\n // \"afterInteractive\" (default), \"beforeInteractive\" (client re-mount), \"worker\"\n load();\n }\n }, [\n src,\n id,\n strategy,\n onLoad,\n onReady,\n onError,\n children,\n dangerouslySetInnerHTML,\n key,\n resolvedNonce,\n rest,\n ]);\n\n // SSR path: only \"beforeInteractive\" renders a <script> tag server-side\n if (typeof window === \"undefined\") {\n if (strategy === \"beforeInteractive\") {\n return React.createElement(\n \"script\",\n buildBeforeInteractiveScriptProps({\n src,\n id,\n rest,\n resolvedNonce,\n dangerouslySetInnerHTML,\n }),\n children,\n );\n }\n // Other strategies don't render during SSR\n return null;\n }\n\n if (strategy === \"beforeInteractive\") {\n return React.createElement(\n \"script\",\n buildBeforeInteractiveScriptProps({\n src,\n id,\n rest,\n resolvedNonce,\n dangerouslySetInnerHTML,\n }),\n children,\n );\n }\n\n // The component itself renders nothing — scripts are injected imperatively\n return null;\n}\n\nexport default Script;\n"],"mappings":"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"}
|
package/dist/shims/server.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { getRequestExecutionContext } from "./request-context.js";
|
|
3
|
+
import { MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER } from "../server/headers.js";
|
|
3
4
|
import { encodeMiddlewareRequestHeaders } from "../server/middleware-request-headers.js";
|
|
4
5
|
import { serializeSetCookie, validateCookieName } from "./internal/cookie-serialize.js";
|
|
5
6
|
import { parseCookieHeader } from "./internal/parse-cookie-header.js";
|
|
@@ -47,20 +48,15 @@ var NextRequest = class extends Request {
|
|
|
47
48
|
constructor(input, init) {
|
|
48
49
|
const { nextConfig: _nextConfig, ...requestInit } = init ?? {};
|
|
49
50
|
if (input instanceof Request) {
|
|
50
|
-
const
|
|
51
|
-
super(
|
|
52
|
-
method: req.method,
|
|
53
|
-
headers: req.headers,
|
|
54
|
-
body: req.body,
|
|
55
|
-
duplex: req.body ? "half" : void 0,
|
|
56
|
-
...requestInit
|
|
57
|
-
});
|
|
51
|
+
const requestInput = requestInit.body === void 0 && input.body && !input.bodyUsed ? input.clone() : input;
|
|
52
|
+
super(requestInput, requestInit);
|
|
58
53
|
} else super(input, requestInit);
|
|
59
54
|
const url = typeof input === "string" ? new URL(input, "http://localhost") : input instanceof URL ? input : new URL(input.url, "http://localhost");
|
|
60
|
-
|
|
55
|
+
const urlConfig = _nextConfig ? {
|
|
61
56
|
basePath: _nextConfig.basePath,
|
|
62
57
|
nextConfig: { i18n: _nextConfig.i18n }
|
|
63
|
-
} : void 0
|
|
58
|
+
} : void 0;
|
|
59
|
+
this._nextUrl = new NextURL(url, void 0, urlConfig);
|
|
64
60
|
this._url = process.env.__NEXT_NO_MIDDLEWARE_URL_NORMALIZE ? url.toString() : this._nextUrl.toString();
|
|
65
61
|
this._cookies = new RequestCookies(this.headers);
|
|
66
62
|
}
|
|
@@ -159,7 +155,7 @@ var NextResponse = class NextResponse extends Response {
|
|
|
159
155
|
*/
|
|
160
156
|
static rewrite(destination, init) {
|
|
161
157
|
const headers = new Headers(init?.headers);
|
|
162
|
-
headers.set(
|
|
158
|
+
headers.set(MIDDLEWARE_REWRITE_HEADER, validateURL(destination));
|
|
163
159
|
if (init?.request?.headers) encodeMiddlewareRequestHeaders(headers, init.request.headers);
|
|
164
160
|
return new NextResponse(null, {
|
|
165
161
|
...init,
|
|
@@ -172,7 +168,7 @@ var NextResponse = class NextResponse extends Response {
|
|
|
172
168
|
*/
|
|
173
169
|
static next(init) {
|
|
174
170
|
const headers = new Headers(init?.headers);
|
|
175
|
-
headers.set(
|
|
171
|
+
headers.set(MIDDLEWARE_NEXT_HEADER, "1");
|
|
176
172
|
if (init?.request?.headers) encodeMiddlewareRequestHeaders(headers, init.request.headers);
|
|
177
173
|
return new NextResponse(null, {
|
|
178
174
|
...init,
|
|
@@ -550,10 +546,10 @@ var MiddlewareResponseCookies = class extends ResponseCookies {
|
|
|
550
546
|
_syncMiddlewareCookieHeader() {
|
|
551
547
|
const cookies = this._responseHeaders.getSetCookie();
|
|
552
548
|
if (cookies.length === 0) {
|
|
553
|
-
this._responseHeaders.delete(
|
|
549
|
+
this._responseHeaders.delete(MIDDLEWARE_SET_COOKIE_HEADER);
|
|
554
550
|
return;
|
|
555
551
|
}
|
|
556
|
-
this._responseHeaders.set(
|
|
552
|
+
this._responseHeaders.set(MIDDLEWARE_SET_COOKIE_HEADER, cookies.join(","));
|
|
557
553
|
}
|
|
558
554
|
};
|
|
559
555
|
/**
|