vinext 0.0.30 → 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -6
- package/dist/build/prerender.d.ts +188 -0
- package/dist/build/prerender.js +675 -0
- package/dist/build/prerender.js.map +1 -0
- package/dist/build/report.d.ts +45 -46
- package/dist/build/report.js +247 -276
- package/dist/build/report.js.map +1 -1
- package/dist/build/run-prerender.d.ts +62 -0
- package/dist/build/run-prerender.js +183 -0
- package/dist/build/run-prerender.js.map +1 -0
- package/dist/build/server-manifest.d.ts +19 -0
- package/dist/build/server-manifest.js +29 -0
- package/dist/build/server-manifest.js.map +1 -0
- package/dist/build/static-export.d.ts +51 -66
- package/dist/build/static-export.js +51 -545
- package/dist/build/static-export.js.map +1 -1
- package/dist/check.d.ts +26 -24
- package/dist/check.js +591 -571
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts +1 -15
- package/dist/cli.js +430 -491
- package/dist/cli.js.map +1 -1
- package/dist/client/entry.d.ts +1 -2
- package/dist/client/entry.js +49 -62
- package/dist/client/entry.js.map +1 -1
- package/dist/client/validate-module-path.d.ts +4 -1
- package/dist/client/validate-module-path.js +23 -28
- package/dist/client/validate-module-path.js.map +1 -1
- package/dist/client/vinext-next-data.d.ts +15 -20
- package/dist/client/vinext-next-data.js +0 -1
- package/dist/cloudflare/index.d.ts +3 -8
- package/dist/cloudflare/index.js +3 -8
- package/dist/cloudflare/kv-cache-handler.d.ts +95 -105
- package/dist/cloudflare/kv-cache-handler.js +354 -380
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.d.ts +36 -34
- package/dist/cloudflare/tpr.js +460 -603
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.d.ts +31 -40
- package/dist/config/config-matchers.js +727 -936
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/dotenv.d.ts +18 -11
- package/dist/config/dotenv.js +79 -84
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +156 -146
- package/dist/config/next-config.js +374 -464
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.d.ts +87 -96
- package/dist/deploy.js +490 -628
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +4 -1
- package/dist/entries/app-browser-entry.js +12 -8
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +33 -20
- package/dist/entries/app-rsc-entry.js +442 -211
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-ssr-entry.d.ts +9 -1
- package/dist/entries/app-ssr-entry.js +61 -28
- package/dist/entries/app-ssr-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.d.ts +6 -2
- package/dist/entries/pages-client-entry.js +30 -33
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-entry-helpers.d.ts +5 -1
- package/dist/entries/pages-entry-helpers.js +17 -14
- package/dist/entries/pages-entry-helpers.js.map +1 -1
- package/dist/entries/pages-server-entry.d.ts +6 -2
- package/dist/entries/pages-server-entry.js +84 -113
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/index.d.ts +82 -62
- package/dist/index.js +2172 -3133
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +40 -37
- package/dist/init.js +201 -258
- package/dist/init.js.map +1 -1
- package/dist/plugins/async-hooks-stub.d.ts +7 -3
- package/dist/plugins/async-hooks-stub.js +39 -42
- package/dist/plugins/async-hooks-stub.js.map +1 -1
- package/dist/plugins/client-reference-dedup.d.ts +7 -3
- package/dist/plugins/client-reference-dedup.js +63 -88
- package/dist/plugins/client-reference-dedup.js.map +1 -1
- package/dist/routing/app-router.d.ts +100 -96
- package/dist/routing/app-router.js +560 -670
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts +18 -15
- package/dist/routing/file-matcher.js +65 -65
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.d.ts +23 -24
- package/dist/routing/pages-router.js +147 -172
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-trie.d.ts +23 -20
- package/dist/routing/route-trie.js +131 -151
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/route-validation.d.ts +5 -2
- package/dist/routing/route-validation.js +98 -130
- package/dist/routing/route-validation.js.map +1 -1
- package/dist/routing/utils.d.ts +10 -7
- package/dist/routing/utils.js +75 -111
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.d.ts +8 -13
- package/dist/server/api-handler.js +161 -193
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-router-entry.d.ts +6 -16
- package/dist/server/app-router-entry.js +26 -54
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/dev-module-runner.d.ts +11 -64
- package/dist/server/dev-module-runner.js +89 -101
- package/dist/server/dev-module-runner.js.map +1 -1
- package/dist/server/dev-origin-check.d.ts +12 -10
- package/dist/server/dev-origin-check.js +98 -108
- package/dist/server/dev-origin-check.js.map +1 -1
- package/dist/server/dev-server.d.ts +17 -14
- package/dist/server/dev-server.js +542 -869
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/html.d.ts +4 -1
- package/dist/server/html.js +25 -26
- package/dist/server/html.js.map +1 -1
- package/dist/server/image-optimization.d.ts +31 -28
- package/dist/server/image-optimization.js +181 -210
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/instrumentation.d.ts +25 -22
- package/dist/server/instrumentation.js +110 -122
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +16 -26
- package/dist/server/isr-cache.js +106 -128
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-routes.d.ts +85 -88
- package/dist/server/metadata-routes.js +270 -317
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-codegen.d.ts +7 -4
- package/dist/server/middleware-codegen.js +61 -61
- package/dist/server/middleware-codegen.js.map +1 -1
- package/dist/server/middleware-request-headers.d.ts +8 -6
- package/dist/server/middleware-request-headers.js +47 -65
- package/dist/server/middleware-request-headers.js.map +1 -1
- package/dist/server/middleware.d.ts +31 -47
- package/dist/server/middleware.js +273 -404
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/normalize-path.d.ts +4 -1
- package/dist/server/normalize-path.js +33 -47
- package/dist/server/normalize-path.js.map +1 -1
- package/dist/server/pages-i18n.d.ts +38 -30
- package/dist/server/pages-i18n.js +112 -139
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/prod-server.d.ts +19 -31
- package/dist/server/prod-server.js +714 -945
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-log.d.ts +18 -12
- package/dist/server/request-log.js +45 -52
- package/dist/server/request-log.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +9 -17
- package/dist/server/request-pipeline.js +133 -184
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/worker-utils.d.ts +4 -1
- package/dist/server/worker-utils.js +31 -37
- package/dist/server/worker-utils.js.map +1 -1
- package/dist/shims/amp.d.ts +5 -2
- package/dist/shims/amp.js +19 -15
- package/dist/shims/amp.js.map +1 -1
- package/dist/shims/app.d.ts +8 -10
- package/dist/shims/app.js +0 -1
- package/dist/shims/cache-runtime.d.ts +20 -45
- package/dist/shims/cache-runtime.js +271 -422
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +130 -121
- package/dist/shims/cache.js +339 -427
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/client-only.d.ts +1 -18
- package/dist/shims/client-only.js +0 -17
- package/dist/shims/compat-router.d.ts +4 -1
- package/dist/shims/compat-router.js +23 -19
- package/dist/shims/compat-router.js.map +1 -1
- package/dist/shims/config.d.ts +7 -5
- package/dist/shims/config.js +16 -23
- package/dist/shims/config.js.map +1 -1
- package/dist/shims/constants.d.ts +119 -118
- package/dist/shims/constants.js +159 -164
- package/dist/shims/constants.js.map +1 -1
- package/dist/shims/document.d.ts +20 -16
- package/dist/shims/document.js +41 -22
- package/dist/shims/document.js.map +1 -1
- package/dist/shims/dynamic.d.ts +13 -22
- package/dist/shims/dynamic.js +122 -136
- package/dist/shims/dynamic.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +22 -15
- package/dist/shims/error-boundary.js +81 -79
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.d.ts +11 -12
- package/dist/shims/error.js +35 -39
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +16 -14
- package/dist/shims/fetch-cache.js +437 -645
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +28 -26
- package/dist/shims/font-google-base.js +238 -325
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-google.d.ts +3 -3
- package/dist/shims/font-google.generated.d.ts +1928 -1924
- package/dist/shims/font-google.generated.js +1928 -2133
- package/dist/shims/font-google.generated.js.map +1 -1
- package/dist/shims/font-google.js +3 -3
- package/dist/shims/font-local.d.ts +28 -26
- package/dist/shims/font-local.js +204 -260
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/form.d.ts +13 -27
- package/dist/shims/form.js +128 -180
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/head-state.d.ts +8 -13
- package/dist/shims/head-state.js +25 -42
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/head.d.ts +16 -20
- package/dist/shims/head.js +172 -250
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +84 -78
- package/dist/shims/headers.js +447 -575
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-context.d.ts +16 -20
- package/dist/shims/i18n-context.js +35 -48
- package/dist/shims/i18n-context.js.map +1 -1
- package/dist/shims/i18n-state.d.ts +8 -14
- package/dist/shims/i18n-state.js +34 -42
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/image-config.d.ts +11 -8
- package/dist/shims/image-config.js +50 -83
- package/dist/shims/image-config.js.map +1 -1
- package/dist/shims/image.d.ts +37 -46
- package/dist/shims/image.js +283 -308
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/api-utils.d.ts +7 -4
- package/dist/shims/internal/api-utils.js +0 -6
- package/dist/shims/internal/app-router-context.d.ts +22 -17
- package/dist/shims/internal/app-router-context.js +17 -13
- package/dist/shims/internal/app-router-context.js.map +1 -1
- package/dist/shims/internal/cookies.d.ts +2 -9
- package/dist/shims/internal/cookies.js +2 -9
- package/dist/shims/internal/parse-cookie-header.d.ts +4 -1
- package/dist/shims/internal/parse-cookie-header.js +29 -29
- package/dist/shims/internal/parse-cookie-header.js.map +1 -1
- package/dist/shims/internal/router-context.d.ts +6 -1
- package/dist/shims/internal/router-context.js +11 -7
- package/dist/shims/internal/router-context.js.map +1 -1
- package/dist/shims/internal/utils.d.ts +40 -37
- package/dist/shims/internal/utils.js +24 -30
- package/dist/shims/internal/utils.js.map +1 -1
- package/dist/shims/internal/work-unit-async-storage.d.ts +6 -10
- package/dist/shims/internal/work-unit-async-storage.js +14 -11
- package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
- package/dist/shims/layout-segment-context.d.ts +11 -14
- package/dist/shims/layout-segment-context.js +24 -23
- package/dist/shims/layout-segment-context.js.map +1 -1
- package/dist/shims/legacy-image.d.ts +39 -46
- package/dist/shims/legacy-image.js +47 -42
- package/dist/shims/legacy-image.js.map +1 -1
- package/dist/shims/link.d.ts +32 -36
- package/dist/shims/link.js +255 -391
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +210 -202
- package/dist/shims/metadata.js +545 -546
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.d.ts +10 -18
- package/dist/shims/navigation-state.js +66 -74
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +59 -63
- package/dist/shims/navigation.js +505 -704
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/og.d.ts +2 -20
- package/dist/shims/og.js +2 -19
- package/dist/shims/readonly-url-search-params.d.ts +8 -5
- package/dist/shims/readonly-url-search-params.js +26 -22
- package/dist/shims/readonly-url-search-params.js.map +1 -1
- package/dist/shims/request-context.d.ts +8 -5
- package/dist/shims/request-context.js +50 -60
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/request-state-types.d.ts +11 -11
- package/dist/shims/request-state-types.js +0 -1
- package/dist/shims/router-state.d.ts +13 -10
- package/dist/shims/router-state.js +34 -43
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +81 -85
- package/dist/shims/router.js +506 -628
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.d.ts +39 -48
- package/dist/shims/script.js +107 -160
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server-only.d.ts +1 -19
- package/dist/shims/server-only.js +0 -18
- package/dist/shims/server.d.ts +175 -164
- package/dist/shims/server.js +462 -478
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/unified-request-context.d.ts +20 -20
- package/dist/shims/unified-request-context.js +81 -99
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/url-safety.d.ts +4 -1
- package/dist/shims/url-safety.js +15 -11
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/shims/url-utils.d.ts +8 -5
- package/dist/shims/url-utils.js +62 -93
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/shims/web-vitals.d.ts +10 -8
- package/dist/shims/web-vitals.js +9 -15
- package/dist/shims/web-vitals.js.map +1 -1
- package/dist/utils/base-path.d.ts +5 -2
- package/dist/utils/base-path.js +21 -19
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/domain-locale.d.ts +17 -9
- package/dist/utils/domain-locale.js +36 -56
- package/dist/utils/domain-locale.js.map +1 -1
- package/dist/utils/hash.d.ts +4 -1
- package/dist/utils/hash.js +19 -17
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/manifest-paths.d.ts +6 -3
- package/dist/utils/manifest-paths.js +15 -16
- package/dist/utils/manifest-paths.js.map +1 -1
- package/dist/utils/project.d.ts +13 -11
- package/dist/utils/project.js +169 -216
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/query.d.ts +8 -6
- package/dist/utils/query.js +57 -67
- package/dist/utils/query.js.map +1 -1
- package/package.json +10 -9
- package/dist/build/report.d.ts.map +0 -1
- package/dist/build/static-export.d.ts.map +0 -1
- package/dist/check.d.ts.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/client/entry.d.ts.map +0 -1
- package/dist/client/validate-module-path.d.ts.map +0 -1
- package/dist/client/vinext-next-data.d.ts.map +0 -1
- package/dist/client/vinext-next-data.js.map +0 -1
- package/dist/cloudflare/index.d.ts.map +0 -1
- package/dist/cloudflare/index.js.map +0 -1
- package/dist/cloudflare/kv-cache-handler.d.ts.map +0 -1
- package/dist/cloudflare/tpr.d.ts.map +0 -1
- package/dist/config/config-matchers.d.ts.map +0 -1
- package/dist/config/dotenv.d.ts.map +0 -1
- package/dist/config/next-config.d.ts.map +0 -1
- package/dist/deploy.d.ts.map +0 -1
- package/dist/entries/app-browser-entry.d.ts.map +0 -1
- package/dist/entries/app-rsc-entry.d.ts.map +0 -1
- package/dist/entries/app-ssr-entry.d.ts.map +0 -1
- package/dist/entries/pages-client-entry.d.ts.map +0 -1
- package/dist/entries/pages-entry-helpers.d.ts.map +0 -1
- package/dist/entries/pages-server-entry.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/init.d.ts.map +0 -1
- package/dist/plugins/async-hooks-stub.d.ts.map +0 -1
- package/dist/plugins/client-reference-dedup.d.ts.map +0 -1
- package/dist/routing/app-router.d.ts.map +0 -1
- package/dist/routing/file-matcher.d.ts.map +0 -1
- package/dist/routing/pages-router.d.ts.map +0 -1
- package/dist/routing/route-trie.d.ts.map +0 -1
- package/dist/routing/route-validation.d.ts.map +0 -1
- package/dist/routing/utils.d.ts.map +0 -1
- package/dist/server/api-handler.d.ts.map +0 -1
- package/dist/server/app-router-entry.d.ts.map +0 -1
- package/dist/server/dev-module-runner.d.ts.map +0 -1
- package/dist/server/dev-origin-check.d.ts.map +0 -1
- package/dist/server/dev-server.d.ts.map +0 -1
- package/dist/server/html.d.ts.map +0 -1
- package/dist/server/image-optimization.d.ts.map +0 -1
- package/dist/server/instrumentation.d.ts.map +0 -1
- package/dist/server/isr-cache.d.ts.map +0 -1
- package/dist/server/metadata-routes.d.ts.map +0 -1
- package/dist/server/middleware-codegen.d.ts.map +0 -1
- package/dist/server/middleware-request-headers.d.ts.map +0 -1
- package/dist/server/middleware.d.ts.map +0 -1
- package/dist/server/normalize-path.d.ts.map +0 -1
- package/dist/server/pages-i18n.d.ts.map +0 -1
- package/dist/server/prod-server.d.ts.map +0 -1
- package/dist/server/request-log.d.ts.map +0 -1
- package/dist/server/request-pipeline.d.ts.map +0 -1
- package/dist/server/worker-utils.d.ts.map +0 -1
- package/dist/shims/amp.d.ts.map +0 -1
- package/dist/shims/app.d.ts.map +0 -1
- package/dist/shims/app.js.map +0 -1
- package/dist/shims/cache-runtime.d.ts.map +0 -1
- package/dist/shims/cache.d.ts.map +0 -1
- package/dist/shims/client-only.d.ts.map +0 -1
- package/dist/shims/client-only.js.map +0 -1
- package/dist/shims/compat-router.d.ts.map +0 -1
- package/dist/shims/config.d.ts.map +0 -1
- package/dist/shims/constants.d.ts.map +0 -1
- package/dist/shims/document.d.ts.map +0 -1
- package/dist/shims/dynamic.d.ts.map +0 -1
- package/dist/shims/error-boundary.d.ts.map +0 -1
- package/dist/shims/error.d.ts.map +0 -1
- package/dist/shims/fetch-cache.d.ts.map +0 -1
- package/dist/shims/font-google-base.d.ts.map +0 -1
- package/dist/shims/font-google.d.ts.map +0 -1
- package/dist/shims/font-google.generated.d.ts.map +0 -1
- package/dist/shims/font-google.js.map +0 -1
- package/dist/shims/font-local.d.ts.map +0 -1
- package/dist/shims/form.d.ts.map +0 -1
- package/dist/shims/head-state.d.ts.map +0 -1
- package/dist/shims/head.d.ts.map +0 -1
- package/dist/shims/headers.d.ts.map +0 -1
- package/dist/shims/i18n-context.d.ts.map +0 -1
- package/dist/shims/i18n-state.d.ts.map +0 -1
- package/dist/shims/image-config.d.ts.map +0 -1
- package/dist/shims/image.d.ts.map +0 -1
- package/dist/shims/internal/api-utils.d.ts.map +0 -1
- package/dist/shims/internal/api-utils.js.map +0 -1
- package/dist/shims/internal/app-router-context.d.ts.map +0 -1
- package/dist/shims/internal/cookies.d.ts.map +0 -1
- package/dist/shims/internal/cookies.js.map +0 -1
- package/dist/shims/internal/parse-cookie-header.d.ts.map +0 -1
- package/dist/shims/internal/router-context.d.ts.map +0 -1
- package/dist/shims/internal/utils.d.ts.map +0 -1
- package/dist/shims/internal/work-unit-async-storage.d.ts.map +0 -1
- package/dist/shims/layout-segment-context.d.ts.map +0 -1
- package/dist/shims/legacy-image.d.ts.map +0 -1
- package/dist/shims/link.d.ts.map +0 -1
- package/dist/shims/metadata.d.ts.map +0 -1
- package/dist/shims/navigation-state.d.ts.map +0 -1
- package/dist/shims/navigation.d.ts.map +0 -1
- package/dist/shims/og.d.ts.map +0 -1
- package/dist/shims/og.js.map +0 -1
- package/dist/shims/readonly-url-search-params.d.ts.map +0 -1
- package/dist/shims/request-context.d.ts.map +0 -1
- package/dist/shims/request-state-types.d.ts.map +0 -1
- package/dist/shims/request-state-types.js.map +0 -1
- package/dist/shims/router-state.d.ts.map +0 -1
- package/dist/shims/router.d.ts.map +0 -1
- package/dist/shims/script.d.ts.map +0 -1
- package/dist/shims/server-only.d.ts.map +0 -1
- package/dist/shims/server-only.js.map +0 -1
- package/dist/shims/server.d.ts.map +0 -1
- package/dist/shims/unified-request-context.d.ts.map +0 -1
- package/dist/shims/url-safety.d.ts.map +0 -1
- package/dist/shims/url-utils.d.ts.map +0 -1
- package/dist/shims/web-vitals.d.ts.map +0 -1
- package/dist/utils/base-path.d.ts.map +0 -1
- package/dist/utils/domain-locale.d.ts.map +0 -1
- package/dist/utils/hash.d.ts.map +0 -1
- package/dist/utils/manifest-paths.d.ts.map +0 -1
- package/dist/utils/project.d.ts.map +0 -1
- package/dist/utils/query.d.ts.map +0 -1
|
@@ -1,87 +1,67 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createValidFileMatcher } from "../routing/file-matcher.js";
|
|
2
|
+
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
3
|
+
import { matchRoute } from "../routing/pages-router.js";
|
|
4
|
+
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
3
5
|
import { _runWithCacheState } from "../shims/cache.js";
|
|
6
|
+
import { buildPagesCacheValue, getRevalidateDuration, isrCacheKey, isrGet, isrSet, setRevalidateDuration, triggerBackgroundRegeneration } from "./isr-cache.js";
|
|
4
7
|
import { runWithPrivateCache } from "../shims/cache-runtime.js";
|
|
5
8
|
import { ensureFetchPatch, runWithFetchCache } from "../shims/fetch-cache.js";
|
|
6
|
-
import {
|
|
7
|
-
// Import server-only state modules to register ALS-backed accessors.
|
|
8
|
-
// These modules must be imported before any rendering occurs.
|
|
9
|
+
import { parseQueryString } from "../utils/query.js";
|
|
9
10
|
import "../shims/router-state.js";
|
|
10
11
|
import { runWithHeadState } from "../shims/head-state.js";
|
|
11
12
|
import { runWithServerInsertedHTMLState } from "../shims/navigation-state.js";
|
|
12
13
|
import { reportRequestError } from "./instrumentation.js";
|
|
13
14
|
import { safeJsonStringify } from "./html.js";
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
15
|
+
import { logRequest, now } from "./request-log.js";
|
|
16
|
+
import { detectLocaleFromAcceptLanguage, extractLocaleFromUrl as extractLocaleFromUrl$1, parseCookieLocaleFromHeader, resolvePagesI18nRequest } from "./pages-i18n.js";
|
|
16
17
|
import fs from "node:fs";
|
|
18
|
+
import path from "node:path";
|
|
17
19
|
import React from "react";
|
|
18
20
|
import { renderToReadableStream } from "react-dom/server.edge";
|
|
19
|
-
|
|
20
|
-
import { createValidFileMatcher } from "../routing/file-matcher.js";
|
|
21
|
-
import { extractLocaleFromUrl as extractLocaleFromUrlShared, detectLocaleFromAcceptLanguage, parseCookieLocaleFromHeader, resolvePagesI18nRequest, } from "./pages-i18n.js";
|
|
21
|
+
//#region src/server/dev-server.ts
|
|
22
22
|
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
* Render a React element to a string using renderToReadableStream.
|
|
24
|
+
*
|
|
25
|
+
* Uses the edge-compatible Web Streams API. Waits for all Suspense
|
|
26
|
+
* boundaries to resolve via stream.allReady before collecting output.
|
|
27
|
+
* Used for _document rendering and error pages (small, non-streaming).
|
|
28
|
+
*/
|
|
29
29
|
async function renderToStringAsync(element) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const stream = await renderToReadableStream(element);
|
|
31
|
+
await stream.allReady;
|
|
32
|
+
return new Response(stream).text();
|
|
33
33
|
}
|
|
34
34
|
async function renderIsrPassToStringAsync(element) {
|
|
35
|
-
|
|
36
|
-
// Reset render-scoped state so it cannot leak from the streamed response
|
|
37
|
-
// render or affect async work that is still draining from that stream.
|
|
38
|
-
// Keep request identity state (pathname/query/locale/executionContext)
|
|
39
|
-
// intact: this second pass still belongs to the same request.
|
|
40
|
-
return await runWithServerInsertedHTMLState(() => runWithHeadState(() => _runWithCacheState(() => runWithPrivateCache(() => runWithFetchCache(async () => renderToStringAsync(element))))));
|
|
35
|
+
return await runWithServerInsertedHTMLState(() => runWithHeadState(() => _runWithCacheState(() => runWithPrivateCache(() => runWithFetchCache(async () => renderToStringAsync(element))))));
|
|
41
36
|
}
|
|
42
37
|
/** Body placeholder used to split the document shell for streaming. */
|
|
43
38
|
const STREAM_BODY_MARKER = "<!--VINEXT_STREAM_BODY-->";
|
|
44
39
|
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
40
|
+
* Stream a Pages Router page response using progressive SSR.
|
|
41
|
+
*
|
|
42
|
+
* Sends the HTML shell (head, layout, Suspense fallbacks) immediately
|
|
43
|
+
* when the React shell is ready, then streams Suspense content as it
|
|
44
|
+
* resolves. This gives the browser content to render while slow data
|
|
45
|
+
* loads are still in flight.
|
|
46
|
+
*
|
|
47
|
+
* `__NEXT_DATA__` and the hydration script are appended after the body
|
|
48
|
+
* stream completes (the data is known before rendering starts, but
|
|
49
|
+
* deferring them reduces TTFB and lets the browser start parsing the
|
|
50
|
+
* shell sooner).
|
|
51
|
+
*/
|
|
57
52
|
async function streamPageToResponse(res, element, options) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Replace __NEXT_MAIN__ with our stream marker
|
|
71
|
-
docHtml = docHtml.replace("__NEXT_MAIN__", STREAM_BODY_MARKER);
|
|
72
|
-
// Inject head tags
|
|
73
|
-
if (headHTML || fontHeadHTML) {
|
|
74
|
-
docHtml = docHtml.replace("</head>", ` ${fontHeadHTML}${headHTML}\n</head>`);
|
|
75
|
-
}
|
|
76
|
-
// Inject scripts: replace placeholder or append before </body>
|
|
77
|
-
docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", scripts);
|
|
78
|
-
if (!docHtml.includes("__NEXT_DATA__")) {
|
|
79
|
-
docHtml = docHtml.replace("</body>", ` ${scripts}\n</body>`);
|
|
80
|
-
}
|
|
81
|
-
shellTemplate = docHtml;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
shellTemplate = `<!DOCTYPE html>
|
|
53
|
+
const { url, server, fontHeadHTML, scripts, DocumentComponent, statusCode = 200, extraHeaders, getHeadHTML } = options;
|
|
54
|
+
const bodyStream = await renderToReadableStream(element);
|
|
55
|
+
const headHTML = getHeadHTML();
|
|
56
|
+
let shellTemplate;
|
|
57
|
+
if (DocumentComponent) {
|
|
58
|
+
let docHtml = await renderToStringAsync(React.createElement(DocumentComponent));
|
|
59
|
+
docHtml = docHtml.replace("__NEXT_MAIN__", STREAM_BODY_MARKER);
|
|
60
|
+
if (headHTML || fontHeadHTML) docHtml = docHtml.replace("</head>", ` ${fontHeadHTML}${headHTML}\n</head>`);
|
|
61
|
+
docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", scripts);
|
|
62
|
+
if (!docHtml.includes("__NEXT_DATA__")) docHtml = docHtml.replace("</body>", ` ${scripts}\n</body>`);
|
|
63
|
+
shellTemplate = docHtml;
|
|
64
|
+
} else shellTemplate = `<!DOCTYPE html>
|
|
85
65
|
<html>
|
|
86
66
|
<head>
|
|
87
67
|
<meta charset="utf-8" />
|
|
@@ -93,596 +73,384 @@ async function streamPageToResponse(res, element, options) {
|
|
|
93
73
|
${scripts}
|
|
94
74
|
</body>
|
|
95
75
|
</html>`;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
res.writeHead(statusCode, headers);
|
|
122
|
-
// Write the document prefix (head, opening body)
|
|
123
|
-
res.write(prefix);
|
|
124
|
-
// Pipe the React body stream through (Suspense content streams progressively)
|
|
125
|
-
const reader = bodyStream.getReader();
|
|
126
|
-
try {
|
|
127
|
-
for (;;) {
|
|
128
|
-
const { done, value } = await reader.read();
|
|
129
|
-
if (done)
|
|
130
|
-
break;
|
|
131
|
-
res.write(value);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
finally {
|
|
135
|
-
reader.releaseLock();
|
|
136
|
-
}
|
|
137
|
-
// Write the document suffix (closing tags, scripts)
|
|
138
|
-
res.end(suffix);
|
|
76
|
+
const transformedShell = await server.transformIndexHtml(url, shellTemplate);
|
|
77
|
+
const markerIdx = transformedShell.indexOf(STREAM_BODY_MARKER);
|
|
78
|
+
const prefix = transformedShell.slice(0, markerIdx);
|
|
79
|
+
const suffix = transformedShell.slice(markerIdx + 25);
|
|
80
|
+
const headers = {
|
|
81
|
+
"Content-Type": "text/html",
|
|
82
|
+
"Transfer-Encoding": "chunked"
|
|
83
|
+
};
|
|
84
|
+
if (extraHeaders) for (const [key, val] of Object.entries(extraHeaders)) if (Array.isArray(val)) res.setHeader(key, val);
|
|
85
|
+
else headers[key] = val;
|
|
86
|
+
res.writeHead(statusCode, headers);
|
|
87
|
+
res.write(prefix);
|
|
88
|
+
const reader = bodyStream.getReader();
|
|
89
|
+
try {
|
|
90
|
+
for (;;) {
|
|
91
|
+
const { done, value } = await reader.read();
|
|
92
|
+
if (done) break;
|
|
93
|
+
res.write(value);
|
|
94
|
+
}
|
|
95
|
+
} finally {
|
|
96
|
+
reader.releaseLock();
|
|
97
|
+
}
|
|
98
|
+
res.end(suffix);
|
|
139
99
|
}
|
|
140
100
|
/** Check if a file exists with any configured page extension. */
|
|
141
101
|
function findFileWithExtensions(basePath, matcher) {
|
|
142
|
-
|
|
102
|
+
return matcher.dottedExtensions.some((ext) => fs.existsSync(basePath + ext));
|
|
143
103
|
}
|
|
144
104
|
/**
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
105
|
+
* Extract locale prefix from a URL path.
|
|
106
|
+
* e.g. /fr/about -> { locale: "fr", url: "/about", hadPrefix: true }
|
|
107
|
+
* /about -> { locale: "en", url: "/about", hadPrefix: false } (defaultLocale)
|
|
108
|
+
*/
|
|
109
|
+
function extractLocaleFromUrl(url, i18nConfig) {
|
|
110
|
+
return extractLocaleFromUrl$1(url, i18nConfig);
|
|
151
111
|
}
|
|
152
112
|
/**
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
113
|
+
* Detect the preferred locale from the Accept-Language header.
|
|
114
|
+
* Returns the best matching locale or null.
|
|
115
|
+
*/
|
|
116
|
+
function detectLocaleFromHeaders(req, i18nConfig) {
|
|
117
|
+
return detectLocaleFromAcceptLanguage(req.headers["accept-language"], i18nConfig);
|
|
158
118
|
}
|
|
159
119
|
/**
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
120
|
+
* Parse the NEXT_LOCALE cookie from a request.
|
|
121
|
+
* Returns the cookie value if it matches a configured locale, otherwise null.
|
|
122
|
+
*/
|
|
123
|
+
function parseCookieLocale(req, i18nConfig) {
|
|
124
|
+
return parseCookieLocaleFromHeader(req.headers.cookie, i18nConfig);
|
|
165
125
|
}
|
|
166
126
|
/**
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
})
|
|
495
|
-
: React.createElement(pageModule.default, freshProps);
|
|
496
|
-
if (routerShim.wrapWithRouterContext) {
|
|
497
|
-
el = routerShim.wrapWithRouterContext(el);
|
|
498
|
-
}
|
|
499
|
-
const freshBody = await renderIsrPassToStringAsync(el);
|
|
500
|
-
// Rebuild __NEXT_DATA__ with fresh props. The hydration
|
|
501
|
-
// script (module URLs) is stable across regenerations —
|
|
502
|
-
// extract it from the cached HTML to avoid duplication.
|
|
503
|
-
const viteRoot = server.config?.root;
|
|
504
|
-
const regenPageUrl = viteRoot
|
|
505
|
-
? "/" + path.relative(viteRoot, route.filePath)
|
|
506
|
-
: route.filePath;
|
|
507
|
-
const regenAppUrl = RegenApp
|
|
508
|
-
? viteRoot
|
|
509
|
-
? "/" + path.relative(viteRoot, path.join(pagesDir, "_app"))
|
|
510
|
-
: path.join(pagesDir, "_app")
|
|
511
|
-
: null;
|
|
512
|
-
const freshNextData = `<script>window.__NEXT_DATA__ = ${safeJsonStringify({
|
|
513
|
-
props: { pageProps: freshProps },
|
|
514
|
-
page: patternToNextFormat(route.pattern),
|
|
515
|
-
query: params,
|
|
516
|
-
buildId: process.env.__VINEXT_BUILD_ID,
|
|
517
|
-
isFallback: false,
|
|
518
|
-
locale: locale ?? currentDefaultLocale,
|
|
519
|
-
locales: i18nConfig?.locales,
|
|
520
|
-
defaultLocale: currentDefaultLocale,
|
|
521
|
-
domainLocales,
|
|
522
|
-
__vinext: {
|
|
523
|
-
pageModuleUrl: regenPageUrl,
|
|
524
|
-
appModuleUrl: regenAppUrl,
|
|
525
|
-
},
|
|
526
|
-
})}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}</script>`;
|
|
527
|
-
const hydrationMatch = cachedHtml.match(/<script type="module">[\s\S]*?<\/script>/);
|
|
528
|
-
const hydrationScript = hydrationMatch?.[0] ?? "";
|
|
529
|
-
const freshHtml = `<!DOCTYPE html><html><head></head><body><div id="__next">${freshBody}</div>${freshNextData}\n ${hydrationScript}</body></html>`;
|
|
530
|
-
await isrSet(cacheKey, buildPagesCacheValue(freshHtml, freshProps), revalidate);
|
|
531
|
-
setRevalidateDuration(cacheKey, revalidate);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
const revalidateSecs = getRevalidateDuration(cacheKey) ?? 60;
|
|
537
|
-
const staleHeaders = {
|
|
538
|
-
"Content-Type": "text/html",
|
|
539
|
-
"X-Vinext-Cache": "STALE",
|
|
540
|
-
"Cache-Control": `s-maxage=${revalidateSecs}, stale-while-revalidate`,
|
|
541
|
-
};
|
|
542
|
-
if (earlyFontLinkHeader)
|
|
543
|
-
staleHeaders["Link"] = earlyFontLinkHeader;
|
|
544
|
-
res.writeHead(200, staleHeaders);
|
|
545
|
-
res.end(transformedHtml);
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
// Cache miss — call getStaticProps normally
|
|
549
|
-
const context = {
|
|
550
|
-
params,
|
|
551
|
-
locale: locale ?? currentDefaultLocale,
|
|
552
|
-
locales: i18nConfig?.locales,
|
|
553
|
-
defaultLocale: currentDefaultLocale,
|
|
554
|
-
};
|
|
555
|
-
const result = await pageModule.getStaticProps(context);
|
|
556
|
-
if (result && "props" in result) {
|
|
557
|
-
pageProps = result.props;
|
|
558
|
-
}
|
|
559
|
-
if (result && "redirect" in result) {
|
|
560
|
-
const { redirect } = result;
|
|
561
|
-
const status = redirect.statusCode ?? (redirect.permanent ? 308 : 307);
|
|
562
|
-
// Sanitize destination to prevent open redirect via protocol-relative URLs.
|
|
563
|
-
// Also normalize backslashes — browsers treat \ as / in URL contexts.
|
|
564
|
-
let dest = redirect.destination;
|
|
565
|
-
if (!dest.startsWith("http://") && !dest.startsWith("https://")) {
|
|
566
|
-
dest = dest.replace(/^[\\/]+/, "/");
|
|
567
|
-
}
|
|
568
|
-
res.writeHead(status, {
|
|
569
|
-
Location: dest,
|
|
570
|
-
});
|
|
571
|
-
res.end();
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
if (result && "notFound" in result && result.notFound) {
|
|
575
|
-
await renderErrorPage(server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
|
|
576
|
-
return;
|
|
577
|
-
}
|
|
578
|
-
// Extract revalidate period for ISR caching after render
|
|
579
|
-
if (typeof result?.revalidate === "number" && result.revalidate > 0) {
|
|
580
|
-
isrRevalidateSeconds = result.revalidate;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
// Try to load _app.tsx if it exists
|
|
584
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
585
|
-
let AppComponent = null;
|
|
586
|
-
const appPath = path.join(pagesDir, "_app");
|
|
587
|
-
if (findFileWithExtensions(appPath, matcher)) {
|
|
588
|
-
try {
|
|
589
|
-
const appModule = await server.ssrLoadModule(appPath);
|
|
590
|
-
AppComponent = appModule.default ?? null;
|
|
591
|
-
}
|
|
592
|
-
catch {
|
|
593
|
-
// _app exists but failed to load
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
// React and ReactDOMServer are imported at the top level as native Node
|
|
597
|
-
// modules. They must NOT go through Vite's SSR module runner because
|
|
598
|
-
// React is CJS and the ESModulesEvaluator doesn't define `module`.
|
|
599
|
-
const createElement = React.createElement;
|
|
600
|
-
let element;
|
|
601
|
-
// wrapWithRouterContext wraps the element in RouterContext.Provider so that
|
|
602
|
-
// next/compat/router's useRouter() returns the real router.
|
|
603
|
-
const wrapWithRouterContext = routerShim.wrapWithRouterContext;
|
|
604
|
-
if (AppComponent) {
|
|
605
|
-
element = createElement(AppComponent, {
|
|
606
|
-
Component: PageComponent,
|
|
607
|
-
pageProps,
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
else {
|
|
611
|
-
element = createElement(PageComponent, pageProps);
|
|
612
|
-
}
|
|
613
|
-
if (wrapWithRouterContext) {
|
|
614
|
-
element = wrapWithRouterContext(element);
|
|
615
|
-
}
|
|
616
|
-
// Reset SSR head collector before rendering so <Head> tags are captured
|
|
617
|
-
const headShim = await server.ssrLoadModule("next/head");
|
|
618
|
-
if (typeof headShim.resetSSRHead === "function") {
|
|
619
|
-
headShim.resetSSRHead();
|
|
620
|
-
}
|
|
621
|
-
// Flush any pending dynamic() preloads so components are ready
|
|
622
|
-
const dynamicShim = await server.ssrLoadModule("next/dynamic");
|
|
623
|
-
if (typeof dynamicShim.flushPreloads === "function") {
|
|
624
|
-
await dynamicShim.flushPreloads();
|
|
625
|
-
}
|
|
626
|
-
// Collect any <Head> tags that were rendered during data fetching
|
|
627
|
-
// (shell head tags — Suspense children's head tags arrive late,
|
|
628
|
-
// matching Next.js behavior)
|
|
629
|
-
// Collect SSR font links (Google Fonts <link> tags) and font class styles
|
|
630
|
-
let fontHeadHTML = "";
|
|
631
|
-
const allFontStyles = [];
|
|
632
|
-
const allFontPreloads = [];
|
|
633
|
-
try {
|
|
634
|
-
const fontGoogle = await server.ssrLoadModule("next/font/google");
|
|
635
|
-
if (typeof fontGoogle.getSSRFontLinks === "function") {
|
|
636
|
-
const fontUrls = fontGoogle.getSSRFontLinks();
|
|
637
|
-
for (const fontUrl of fontUrls) {
|
|
638
|
-
const safeFontUrl = fontUrl.replace(/&/g, "&").replace(/"/g, """);
|
|
639
|
-
fontHeadHTML += `<link rel="stylesheet" href="${safeFontUrl}" />\n `;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
if (typeof fontGoogle.getSSRFontStyles === "function") {
|
|
643
|
-
allFontStyles.push(...fontGoogle.getSSRFontStyles());
|
|
644
|
-
}
|
|
645
|
-
// Collect preloads from self-hosted Google fonts
|
|
646
|
-
if (typeof fontGoogle.getSSRFontPreloads === "function") {
|
|
647
|
-
allFontPreloads.push(...fontGoogle.getSSRFontPreloads());
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
catch {
|
|
651
|
-
// next/font/google not used — skip
|
|
652
|
-
}
|
|
653
|
-
try {
|
|
654
|
-
const fontLocal = await server.ssrLoadModule("next/font/local");
|
|
655
|
-
if (typeof fontLocal.getSSRFontStyles === "function") {
|
|
656
|
-
allFontStyles.push(...fontLocal.getSSRFontStyles());
|
|
657
|
-
}
|
|
658
|
-
// Collect preloads from local font files
|
|
659
|
-
if (typeof fontLocal.getSSRFontPreloads === "function") {
|
|
660
|
-
allFontPreloads.push(...fontLocal.getSSRFontPreloads());
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
catch {
|
|
664
|
-
// next/font/local not used — skip
|
|
665
|
-
}
|
|
666
|
-
// Emit <link rel="preload"> for all collected font files (Google + local)
|
|
667
|
-
for (const { href, type } of allFontPreloads) {
|
|
668
|
-
// Escape href/type to prevent HTML attribute injection (defense-in-depth;
|
|
669
|
-
// Vite-resolved asset paths should never contain special chars).
|
|
670
|
-
const safeHref = href.replace(/&/g, "&").replace(/"/g, """);
|
|
671
|
-
const safeType = type.replace(/&/g, "&").replace(/"/g, """);
|
|
672
|
-
fontHeadHTML += `<link rel="preload" href="${safeHref}" as="font" type="${safeType}" crossorigin />\n `;
|
|
673
|
-
}
|
|
674
|
-
if (allFontStyles.length > 0) {
|
|
675
|
-
fontHeadHTML += `<style data-vinext-fonts>${allFontStyles.join("\n")}</style>\n `;
|
|
676
|
-
}
|
|
677
|
-
// Convert absolute file paths to Vite-servable URLs (relative to root)
|
|
678
|
-
const viteRoot = server.config.root;
|
|
679
|
-
const pageModuleUrl = "/" + path.relative(viteRoot, route.filePath);
|
|
680
|
-
const appModuleUrl = AppComponent
|
|
681
|
-
? "/" + path.relative(viteRoot, path.join(pagesDir, "_app"))
|
|
682
|
-
: null;
|
|
683
|
-
// Hydration entry: inline script that imports the page and hydrates.
|
|
684
|
-
// Stores the React root and page loader for client-side navigation.
|
|
685
|
-
const hydrationScript = `
|
|
127
|
+
* Create an SSR request handler for the Pages Router.
|
|
128
|
+
*
|
|
129
|
+
* For each request:
|
|
130
|
+
* 1. Match the URL against discovered routes
|
|
131
|
+
* 2. Load the page module via Vite's SSR module loader
|
|
132
|
+
* 3. Call getServerSideProps/getStaticProps if present
|
|
133
|
+
* 4. Render the component to HTML
|
|
134
|
+
* 5. Wrap in _document shell and send response
|
|
135
|
+
*/
|
|
136
|
+
function createSSRHandler(server, routes, pagesDir, i18nConfig, fileMatcher, basePath = "", trailingSlash = false) {
|
|
137
|
+
const matcher = fileMatcher ?? createValidFileMatcher();
|
|
138
|
+
const _alsRegistration = Promise.all([server.ssrLoadModule("vinext/head-state"), server.ssrLoadModule("vinext/router-state")]);
|
|
139
|
+
_alsRegistration.catch(() => {});
|
|
140
|
+
return async (req, res, url, statusCode) => {
|
|
141
|
+
const _reqStart = now();
|
|
142
|
+
let _compileEnd;
|
|
143
|
+
let _renderEnd;
|
|
144
|
+
res.on("finish", () => {
|
|
145
|
+
const totalMs = now() - _reqStart;
|
|
146
|
+
const compileMs = _compileEnd !== void 0 ? Math.round(_compileEnd - _reqStart) : void 0;
|
|
147
|
+
const renderMs = _renderEnd !== void 0 && _compileEnd !== void 0 ? Math.round(_renderEnd - _compileEnd) : void 0;
|
|
148
|
+
logRequest({
|
|
149
|
+
method: req.method ?? "GET",
|
|
150
|
+
url,
|
|
151
|
+
status: res.statusCode,
|
|
152
|
+
totalMs,
|
|
153
|
+
compileMs,
|
|
154
|
+
renderMs
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
let locale;
|
|
158
|
+
let localeStrippedUrl = url;
|
|
159
|
+
let currentDefaultLocale;
|
|
160
|
+
const domainLocales = i18nConfig?.domains;
|
|
161
|
+
if (i18nConfig) {
|
|
162
|
+
const resolved = resolvePagesI18nRequest(url, i18nConfig, req.headers, req.headers.host, basePath, trailingSlash);
|
|
163
|
+
locale = resolved.locale;
|
|
164
|
+
localeStrippedUrl = resolved.url;
|
|
165
|
+
currentDefaultLocale = resolved.domainLocale?.defaultLocale ?? i18nConfig.defaultLocale;
|
|
166
|
+
if (resolved.redirectUrl) {
|
|
167
|
+
res.writeHead(307, { Location: resolved.redirectUrl });
|
|
168
|
+
res.end();
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const match = matchRoute(localeStrippedUrl, routes);
|
|
173
|
+
if (!match) {
|
|
174
|
+
await renderErrorPage(server, req, res, url, pagesDir, 404, void 0, matcher);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const { route, params } = match;
|
|
178
|
+
return runWithRequestContext(createRequestContext(), async () => {
|
|
179
|
+
ensureFetchPatch();
|
|
180
|
+
try {
|
|
181
|
+
await _alsRegistration;
|
|
182
|
+
const routerShim = await server.ssrLoadModule("next/router");
|
|
183
|
+
if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
|
|
184
|
+
pathname: patternToNextFormat(route.pattern),
|
|
185
|
+
query: {
|
|
186
|
+
...params,
|
|
187
|
+
...parseQueryString(url)
|
|
188
|
+
},
|
|
189
|
+
asPath: url,
|
|
190
|
+
locale: locale ?? currentDefaultLocale,
|
|
191
|
+
locales: i18nConfig?.locales,
|
|
192
|
+
defaultLocale: currentDefaultLocale,
|
|
193
|
+
domainLocales
|
|
194
|
+
});
|
|
195
|
+
if (i18nConfig) {
|
|
196
|
+
await server.ssrLoadModule("vinext/i18n-state");
|
|
197
|
+
const i18nCtx = await server.ssrLoadModule("vinext/i18n-context");
|
|
198
|
+
if (typeof i18nCtx.setI18nContext === "function") i18nCtx.setI18nContext({
|
|
199
|
+
locale: locale ?? currentDefaultLocale,
|
|
200
|
+
locales: i18nConfig.locales,
|
|
201
|
+
defaultLocale: currentDefaultLocale,
|
|
202
|
+
domainLocales,
|
|
203
|
+
hostname: req.headers.host?.split(":", 1)[0]
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const pageModule = await server.ssrLoadModule(route.filePath);
|
|
207
|
+
_compileEnd = now();
|
|
208
|
+
const PageComponent = pageModule.default;
|
|
209
|
+
if (!PageComponent) {
|
|
210
|
+
console.error(`[vinext] Page ${route.filePath} has no default export`);
|
|
211
|
+
res.statusCode = 500;
|
|
212
|
+
res.end("Page has no default export");
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
let pageProps = {};
|
|
216
|
+
let isrRevalidateSeconds = null;
|
|
217
|
+
if (typeof pageModule.getStaticPaths === "function" && route.isDynamic) {
|
|
218
|
+
const pathsResult = await pageModule.getStaticPaths({
|
|
219
|
+
locales: i18nConfig?.locales ?? [],
|
|
220
|
+
defaultLocale: currentDefaultLocale ?? ""
|
|
221
|
+
});
|
|
222
|
+
if ((pathsResult?.fallback ?? false) === false) {
|
|
223
|
+
if (!(pathsResult?.paths ?? []).some((p) => {
|
|
224
|
+
return Object.entries(p.params).every(([key, val]) => {
|
|
225
|
+
const actual = params[key];
|
|
226
|
+
if (Array.isArray(val)) return Array.isArray(actual) && val.join("/") === actual.join("/");
|
|
227
|
+
return String(val) === String(actual);
|
|
228
|
+
});
|
|
229
|
+
})) {
|
|
230
|
+
await renderErrorPage(server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext, matcher);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const gsspExtraHeaders = {};
|
|
236
|
+
if (typeof pageModule.getServerSideProps === "function") {
|
|
237
|
+
const headersBeforeGSSP = new Set(Object.keys(res.getHeaders()));
|
|
238
|
+
const context = {
|
|
239
|
+
params,
|
|
240
|
+
req,
|
|
241
|
+
res,
|
|
242
|
+
query: parseQueryString(url),
|
|
243
|
+
resolvedUrl: localeStrippedUrl,
|
|
244
|
+
locale: locale ?? currentDefaultLocale,
|
|
245
|
+
locales: i18nConfig?.locales,
|
|
246
|
+
defaultLocale: currentDefaultLocale
|
|
247
|
+
};
|
|
248
|
+
const result = await pageModule.getServerSideProps(context);
|
|
249
|
+
if (res.writableEnded) return;
|
|
250
|
+
if (result && "props" in result) pageProps = result.props;
|
|
251
|
+
if (result && "redirect" in result) {
|
|
252
|
+
const { redirect } = result;
|
|
253
|
+
const status = redirect.statusCode ?? (redirect.permanent ? 308 : 307);
|
|
254
|
+
let dest = redirect.destination;
|
|
255
|
+
if (!dest.startsWith("http://") && !dest.startsWith("https://")) dest = dest.replace(/^[\\/]+/, "/");
|
|
256
|
+
res.writeHead(status, { Location: dest });
|
|
257
|
+
res.end();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (result && "notFound" in result && result.notFound) {
|
|
261
|
+
await renderErrorPage(server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (!statusCode && res.statusCode !== 200) statusCode = res.statusCode;
|
|
265
|
+
const headersAfterGSSP = res.getHeaders();
|
|
266
|
+
for (const [key, val] of Object.entries(headersAfterGSSP)) {
|
|
267
|
+
if (headersBeforeGSSP.has(key) || val == null) continue;
|
|
268
|
+
res.removeHeader(key);
|
|
269
|
+
if (Array.isArray(val)) gsspExtraHeaders[key] = val.map(String);
|
|
270
|
+
else gsspExtraHeaders[key] = String(val);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
let earlyFontLinkHeader = "";
|
|
274
|
+
try {
|
|
275
|
+
const earlyPreloads = [];
|
|
276
|
+
const fontGoogleEarly = await server.ssrLoadModule("next/font/google");
|
|
277
|
+
if (typeof fontGoogleEarly.getSSRFontPreloads === "function") earlyPreloads.push(...fontGoogleEarly.getSSRFontPreloads());
|
|
278
|
+
const fontLocalEarly = await server.ssrLoadModule("next/font/local");
|
|
279
|
+
if (typeof fontLocalEarly.getSSRFontPreloads === "function") earlyPreloads.push(...fontLocalEarly.getSSRFontPreloads());
|
|
280
|
+
if (earlyPreloads.length > 0) earlyFontLinkHeader = earlyPreloads.map((p) => `<${p.href}>; rel=preload; as=font; type=${p.type}; crossorigin`).join(", ");
|
|
281
|
+
} catch {}
|
|
282
|
+
if (typeof pageModule.getStaticProps === "function") {
|
|
283
|
+
const cacheKey = isrCacheKey("pages", url.split("?")[0], process.env.__VINEXT_BUILD_ID);
|
|
284
|
+
const cached = await isrGet(cacheKey);
|
|
285
|
+
if (cached && !cached.isStale && cached.value.value?.kind === "PAGES") {
|
|
286
|
+
const cachedHtml = cached.value.value.html;
|
|
287
|
+
const transformedHtml = await server.transformIndexHtml(url, cachedHtml);
|
|
288
|
+
const revalidateSecs = getRevalidateDuration(cacheKey) ?? 60;
|
|
289
|
+
const hitHeaders = {
|
|
290
|
+
"Content-Type": "text/html",
|
|
291
|
+
"X-Vinext-Cache": "HIT",
|
|
292
|
+
"Cache-Control": `s-maxage=${revalidateSecs}, stale-while-revalidate`
|
|
293
|
+
};
|
|
294
|
+
if (earlyFontLinkHeader) hitHeaders["Link"] = earlyFontLinkHeader;
|
|
295
|
+
res.writeHead(200, hitHeaders);
|
|
296
|
+
res.end(transformedHtml);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (cached && cached.isStale && cached.value.value?.kind === "PAGES") {
|
|
300
|
+
const cachedHtml = cached.value.value.html;
|
|
301
|
+
const transformedHtml = await server.transformIndexHtml(url, cachedHtml);
|
|
302
|
+
triggerBackgroundRegeneration(cacheKey, async () => {
|
|
303
|
+
return runWithRequestContext(createRequestContext({ executionContext: null }), async () => {
|
|
304
|
+
ensureFetchPatch();
|
|
305
|
+
const freshResult = await pageModule.getStaticProps({
|
|
306
|
+
params,
|
|
307
|
+
locale: locale ?? currentDefaultLocale,
|
|
308
|
+
locales: i18nConfig?.locales,
|
|
309
|
+
defaultLocale: currentDefaultLocale
|
|
310
|
+
});
|
|
311
|
+
if (freshResult && "props" in freshResult) {
|
|
312
|
+
const revalidate = typeof freshResult.revalidate === "number" ? freshResult.revalidate : 0;
|
|
313
|
+
if (revalidate > 0) {
|
|
314
|
+
const freshProps = freshResult.props;
|
|
315
|
+
if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext({
|
|
316
|
+
pathname: patternToNextFormat(route.pattern),
|
|
317
|
+
query: {
|
|
318
|
+
...params,
|
|
319
|
+
...parseQueryString(url)
|
|
320
|
+
},
|
|
321
|
+
asPath: url,
|
|
322
|
+
locale: locale ?? currentDefaultLocale,
|
|
323
|
+
locales: i18nConfig?.locales,
|
|
324
|
+
defaultLocale: currentDefaultLocale,
|
|
325
|
+
domainLocales
|
|
326
|
+
});
|
|
327
|
+
if (i18nConfig) {
|
|
328
|
+
await server.ssrLoadModule("vinext/i18n-state");
|
|
329
|
+
const i18nCtx = await server.ssrLoadModule("vinext/i18n-context");
|
|
330
|
+
if (typeof i18nCtx.setI18nContext === "function") i18nCtx.setI18nContext({
|
|
331
|
+
locale: locale ?? currentDefaultLocale,
|
|
332
|
+
locales: i18nConfig.locales,
|
|
333
|
+
defaultLocale: currentDefaultLocale,
|
|
334
|
+
domainLocales,
|
|
335
|
+
hostname: req.headers.host?.split(":", 1)[0]
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
let RegenApp = null;
|
|
339
|
+
const appPath = path.join(pagesDir, "_app");
|
|
340
|
+
if (findFileWithExtensions(appPath, matcher)) try {
|
|
341
|
+
RegenApp = (await server.ssrLoadModule(appPath)).default ?? null;
|
|
342
|
+
} catch {}
|
|
343
|
+
let el = RegenApp ? React.createElement(RegenApp, {
|
|
344
|
+
Component: pageModule.default,
|
|
345
|
+
pageProps: freshProps
|
|
346
|
+
}) : React.createElement(pageModule.default, freshProps);
|
|
347
|
+
if (routerShim.wrapWithRouterContext) el = routerShim.wrapWithRouterContext(el);
|
|
348
|
+
const freshBody = await renderIsrPassToStringAsync(el);
|
|
349
|
+
const viteRoot = server.config?.root;
|
|
350
|
+
const regenPageUrl = viteRoot ? "/" + path.relative(viteRoot, route.filePath) : route.filePath;
|
|
351
|
+
const regenAppUrl = RegenApp ? viteRoot ? "/" + path.relative(viteRoot, path.join(pagesDir, "_app")) : path.join(pagesDir, "_app") : null;
|
|
352
|
+
await isrSet(cacheKey, buildPagesCacheValue(`<!DOCTYPE html><html><head></head><body><div id="__next">${freshBody}</div>${`<script>window.__NEXT_DATA__ = ${safeJsonStringify({
|
|
353
|
+
props: { pageProps: freshProps },
|
|
354
|
+
page: patternToNextFormat(route.pattern),
|
|
355
|
+
query: params,
|
|
356
|
+
buildId: process.env.__VINEXT_BUILD_ID,
|
|
357
|
+
isFallback: false,
|
|
358
|
+
locale: locale ?? currentDefaultLocale,
|
|
359
|
+
locales: i18nConfig?.locales,
|
|
360
|
+
defaultLocale: currentDefaultLocale,
|
|
361
|
+
domainLocales,
|
|
362
|
+
__vinext: {
|
|
363
|
+
pageModuleUrl: regenPageUrl,
|
|
364
|
+
appModuleUrl: regenAppUrl
|
|
365
|
+
}
|
|
366
|
+
})}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}<\/script>`}\n ${cachedHtml.match(/<script type="module">[\s\S]*?<\/script>/)?.[0] ?? ""}</body></html>`, freshProps), revalidate);
|
|
367
|
+
setRevalidateDuration(cacheKey, revalidate);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
const revalidateSecs = getRevalidateDuration(cacheKey) ?? 60;
|
|
373
|
+
const staleHeaders = {
|
|
374
|
+
"Content-Type": "text/html",
|
|
375
|
+
"X-Vinext-Cache": "STALE",
|
|
376
|
+
"Cache-Control": `s-maxage=${revalidateSecs}, stale-while-revalidate`
|
|
377
|
+
};
|
|
378
|
+
if (earlyFontLinkHeader) staleHeaders["Link"] = earlyFontLinkHeader;
|
|
379
|
+
res.writeHead(200, staleHeaders);
|
|
380
|
+
res.end(transformedHtml);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const context = {
|
|
384
|
+
params,
|
|
385
|
+
locale: locale ?? currentDefaultLocale,
|
|
386
|
+
locales: i18nConfig?.locales,
|
|
387
|
+
defaultLocale: currentDefaultLocale
|
|
388
|
+
};
|
|
389
|
+
const result = await pageModule.getStaticProps(context);
|
|
390
|
+
if (result && "props" in result) pageProps = result.props;
|
|
391
|
+
if (result && "redirect" in result) {
|
|
392
|
+
const { redirect } = result;
|
|
393
|
+
const status = redirect.statusCode ?? (redirect.permanent ? 308 : 307);
|
|
394
|
+
let dest = redirect.destination;
|
|
395
|
+
if (!dest.startsWith("http://") && !dest.startsWith("https://")) dest = dest.replace(/^[\\/]+/, "/");
|
|
396
|
+
res.writeHead(status, { Location: dest });
|
|
397
|
+
res.end();
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (result && "notFound" in result && result.notFound) {
|
|
401
|
+
await renderErrorPage(server, req, res, url, pagesDir, 404, routerShim.wrapWithRouterContext);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (typeof result?.revalidate === "number" && result.revalidate > 0) isrRevalidateSeconds = result.revalidate;
|
|
405
|
+
}
|
|
406
|
+
let AppComponent = null;
|
|
407
|
+
const appPath = path.join(pagesDir, "_app");
|
|
408
|
+
if (findFileWithExtensions(appPath, matcher)) try {
|
|
409
|
+
AppComponent = (await server.ssrLoadModule(appPath)).default ?? null;
|
|
410
|
+
} catch {}
|
|
411
|
+
const createElement = React.createElement;
|
|
412
|
+
let element;
|
|
413
|
+
const wrapWithRouterContext = routerShim.wrapWithRouterContext;
|
|
414
|
+
if (AppComponent) element = createElement(AppComponent, {
|
|
415
|
+
Component: PageComponent,
|
|
416
|
+
pageProps
|
|
417
|
+
});
|
|
418
|
+
else element = createElement(PageComponent, pageProps);
|
|
419
|
+
if (wrapWithRouterContext) element = wrapWithRouterContext(element);
|
|
420
|
+
const headShim = await server.ssrLoadModule("next/head");
|
|
421
|
+
if (typeof headShim.resetSSRHead === "function") headShim.resetSSRHead();
|
|
422
|
+
const dynamicShim = await server.ssrLoadModule("next/dynamic");
|
|
423
|
+
if (typeof dynamicShim.flushPreloads === "function") await dynamicShim.flushPreloads();
|
|
424
|
+
let fontHeadHTML = "";
|
|
425
|
+
const allFontStyles = [];
|
|
426
|
+
const allFontPreloads = [];
|
|
427
|
+
try {
|
|
428
|
+
const fontGoogle = await server.ssrLoadModule("next/font/google");
|
|
429
|
+
if (typeof fontGoogle.getSSRFontLinks === "function") {
|
|
430
|
+
const fontUrls = fontGoogle.getSSRFontLinks();
|
|
431
|
+
for (const fontUrl of fontUrls) {
|
|
432
|
+
const safeFontUrl = fontUrl.replace(/&/g, "&").replace(/"/g, """);
|
|
433
|
+
fontHeadHTML += `<link rel="stylesheet" href="${safeFontUrl}" />\n `;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (typeof fontGoogle.getSSRFontStyles === "function") allFontStyles.push(...fontGoogle.getSSRFontStyles());
|
|
437
|
+
if (typeof fontGoogle.getSSRFontPreloads === "function") allFontPreloads.push(...fontGoogle.getSSRFontPreloads());
|
|
438
|
+
} catch {}
|
|
439
|
+
try {
|
|
440
|
+
const fontLocal = await server.ssrLoadModule("next/font/local");
|
|
441
|
+
if (typeof fontLocal.getSSRFontStyles === "function") allFontStyles.push(...fontLocal.getSSRFontStyles());
|
|
442
|
+
if (typeof fontLocal.getSSRFontPreloads === "function") allFontPreloads.push(...fontLocal.getSSRFontPreloads());
|
|
443
|
+
} catch {}
|
|
444
|
+
for (const { href, type } of allFontPreloads) {
|
|
445
|
+
const safeHref = href.replace(/&/g, "&").replace(/"/g, """);
|
|
446
|
+
const safeType = type.replace(/&/g, "&").replace(/"/g, """);
|
|
447
|
+
fontHeadHTML += `<link rel="preload" href="${safeHref}" as="font" type="${safeType}" crossorigin />\n `;
|
|
448
|
+
}
|
|
449
|
+
if (allFontStyles.length > 0) fontHeadHTML += `<style data-vinext-fonts>${allFontStyles.join("\n")}</style>\n `;
|
|
450
|
+
const viteRoot = server.config.root;
|
|
451
|
+
const pageModuleUrl = "/" + path.relative(viteRoot, route.filePath);
|
|
452
|
+
const appModuleUrl = AppComponent ? "/" + path.relative(viteRoot, path.join(pagesDir, "_app")) : null;
|
|
453
|
+
const hydrationScript = `
|
|
686
454
|
<script type="module">
|
|
687
455
|
import React from "react";
|
|
688
456
|
import { hydrateRoot } from "react-dom/client";
|
|
@@ -695,14 +463,12 @@ async function hydrate() {
|
|
|
695
463
|
const pageModule = await import("${pageModuleUrl}");
|
|
696
464
|
const PageComponent = pageModule.default;
|
|
697
465
|
let element;
|
|
698
|
-
${appModuleUrl
|
|
699
|
-
? `
|
|
466
|
+
${appModuleUrl ? `
|
|
700
467
|
const appModule = await import("${appModuleUrl}");
|
|
701
468
|
const AppComponent = appModule.default;
|
|
702
469
|
window.__VINEXT_APP__ = AppComponent;
|
|
703
470
|
element = React.createElement(AppComponent, { Component: PageComponent, pageProps });
|
|
704
|
-
`
|
|
705
|
-
: `
|
|
471
|
+
` : `
|
|
706
472
|
element = React.createElement(PageComponent, pageProps);
|
|
707
473
|
`}
|
|
708
474
|
element = wrapWithRouterContext(element);
|
|
@@ -710,217 +476,126 @@ async function hydrate() {
|
|
|
710
476
|
window.__VINEXT_ROOT__ = root;
|
|
711
477
|
}
|
|
712
478
|
hydrate();
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
let isrElement = AppComponent
|
|
786
|
-
? createElement(AppComponent, {
|
|
787
|
-
Component: pageModule.default,
|
|
788
|
-
pageProps,
|
|
789
|
-
})
|
|
790
|
-
: createElement(pageModule.default, pageProps);
|
|
791
|
-
if (wrapWithRouterContext) {
|
|
792
|
-
isrElement = wrapWithRouterContext(isrElement);
|
|
793
|
-
}
|
|
794
|
-
const isrBodyHtml = await renderIsrPassToStringAsync(isrElement);
|
|
795
|
-
const isrHtml = `<!DOCTYPE html><html><head></head><body><div id="__next">${isrBodyHtml}</div>${allScripts}</body></html>`;
|
|
796
|
-
const cacheKey = isrCacheKey("pages", url.split("?")[0],
|
|
797
|
-
// __VINEXT_BUILD_ID is a compile-time define — undefined in dev,
|
|
798
|
-
// which is fine: dev doesn't need cross-deploy cache isolation.
|
|
799
|
-
process.env.__VINEXT_BUILD_ID);
|
|
800
|
-
await isrSet(cacheKey, buildPagesCacheValue(isrHtml, pageProps), isrRevalidateSeconds);
|
|
801
|
-
setRevalidateDuration(cacheKey, isrRevalidateSeconds);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
catch (e) {
|
|
805
|
-
// Let Vite fix the stack trace for better dev experience
|
|
806
|
-
server.ssrFixStacktrace(e);
|
|
807
|
-
console.error(e);
|
|
808
|
-
// Report error via instrumentation hook if registered
|
|
809
|
-
reportRequestError(e instanceof Error ? e : new Error(String(e)), {
|
|
810
|
-
path: url,
|
|
811
|
-
method: req.method ?? "GET",
|
|
812
|
-
headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [
|
|
813
|
-
k,
|
|
814
|
-
Array.isArray(v) ? v.join(", ") : String(v ?? ""),
|
|
815
|
-
])),
|
|
816
|
-
}, {
|
|
817
|
-
routerKind: "Pages Router",
|
|
818
|
-
routePath: route.pattern,
|
|
819
|
-
routeType: "render",
|
|
820
|
-
}).catch(() => {
|
|
821
|
-
/* ignore reporting errors */
|
|
822
|
-
});
|
|
823
|
-
// Try to render custom 500 error page
|
|
824
|
-
try {
|
|
825
|
-
await renderErrorPage(server, req, res, url, pagesDir, 500, undefined, matcher);
|
|
826
|
-
}
|
|
827
|
-
catch (fallbackErr) {
|
|
828
|
-
// If error page itself fails, fall back to plain text.
|
|
829
|
-
// This is a dev-only code path (prod uses prod-server.ts), so
|
|
830
|
-
// include the error message for debugging.
|
|
831
|
-
res.statusCode = 500;
|
|
832
|
-
res.end(`Internal Server Error: ${fallbackErr.message}`);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
finally {
|
|
836
|
-
// Cleanup is handled by unified ALS scope unwinding.
|
|
837
|
-
}
|
|
838
|
-
});
|
|
839
|
-
};
|
|
479
|
+
<\/script>`;
|
|
480
|
+
const nextDataScript = `<script>window.__NEXT_DATA__ = ${safeJsonStringify({
|
|
481
|
+
props: { pageProps },
|
|
482
|
+
page: patternToNextFormat(route.pattern),
|
|
483
|
+
query: params,
|
|
484
|
+
buildId: process.env.__VINEXT_BUILD_ID,
|
|
485
|
+
isFallback: false,
|
|
486
|
+
locale: locale ?? currentDefaultLocale,
|
|
487
|
+
locales: i18nConfig?.locales,
|
|
488
|
+
defaultLocale: currentDefaultLocale,
|
|
489
|
+
domainLocales,
|
|
490
|
+
__vinext: {
|
|
491
|
+
pageModuleUrl,
|
|
492
|
+
appModuleUrl
|
|
493
|
+
}
|
|
494
|
+
})}${i18nConfig ? `;window.__VINEXT_LOCALE__=${safeJsonStringify(locale ?? currentDefaultLocale)};window.__VINEXT_LOCALES__=${safeJsonStringify(i18nConfig.locales)};window.__VINEXT_DEFAULT_LOCALE__=${safeJsonStringify(currentDefaultLocale)}` : ""}<\/script>`;
|
|
495
|
+
const docPath = path.join(pagesDir, "_document");
|
|
496
|
+
let DocumentComponent = null;
|
|
497
|
+
if (findFileWithExtensions(docPath, matcher)) try {
|
|
498
|
+
DocumentComponent = (await server.ssrLoadModule(docPath)).default ?? null;
|
|
499
|
+
} catch {}
|
|
500
|
+
const allScripts = `${nextDataScript}\n ${hydrationScript}`;
|
|
501
|
+
const extraHeaders = { ...gsspExtraHeaders };
|
|
502
|
+
if (isrRevalidateSeconds) {
|
|
503
|
+
extraHeaders["Cache-Control"] = `s-maxage=${isrRevalidateSeconds}, stale-while-revalidate`;
|
|
504
|
+
extraHeaders["X-Vinext-Cache"] = "MISS";
|
|
505
|
+
}
|
|
506
|
+
if (allFontPreloads.length > 0) extraHeaders["Link"] = allFontPreloads.map((p) => `<${p.href}>; rel=preload; as=font; type=${p.type}; crossorigin`).join(", ");
|
|
507
|
+
await streamPageToResponse(res, element, {
|
|
508
|
+
url,
|
|
509
|
+
server,
|
|
510
|
+
fontHeadHTML,
|
|
511
|
+
scripts: allScripts,
|
|
512
|
+
DocumentComponent,
|
|
513
|
+
statusCode,
|
|
514
|
+
extraHeaders,
|
|
515
|
+
getHeadHTML: () => typeof headShim.getSSRHeadHTML === "function" ? headShim.getSSRHeadHTML() : ""
|
|
516
|
+
});
|
|
517
|
+
_renderEnd = now();
|
|
518
|
+
if (typeof routerShim.setSSRContext === "function") routerShim.setSSRContext(null);
|
|
519
|
+
if (isrRevalidateSeconds !== null && isrRevalidateSeconds > 0) {
|
|
520
|
+
let isrElement = AppComponent ? createElement(AppComponent, {
|
|
521
|
+
Component: pageModule.default,
|
|
522
|
+
pageProps
|
|
523
|
+
}) : createElement(pageModule.default, pageProps);
|
|
524
|
+
if (wrapWithRouterContext) isrElement = wrapWithRouterContext(isrElement);
|
|
525
|
+
const isrHtml = `<!DOCTYPE html><html><head></head><body><div id="__next">${await renderIsrPassToStringAsync(isrElement)}</div>${allScripts}</body></html>`;
|
|
526
|
+
const cacheKey = isrCacheKey("pages", url.split("?")[0], process.env.__VINEXT_BUILD_ID);
|
|
527
|
+
await isrSet(cacheKey, buildPagesCacheValue(isrHtml, pageProps), isrRevalidateSeconds);
|
|
528
|
+
setRevalidateDuration(cacheKey, isrRevalidateSeconds);
|
|
529
|
+
}
|
|
530
|
+
} catch (e) {
|
|
531
|
+
server.ssrFixStacktrace?.(e);
|
|
532
|
+
console.error(e);
|
|
533
|
+
reportRequestError(e instanceof Error ? e : new Error(String(e)), {
|
|
534
|
+
path: url,
|
|
535
|
+
method: req.method ?? "GET",
|
|
536
|
+
headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v ?? "")]))
|
|
537
|
+
}, {
|
|
538
|
+
routerKind: "Pages Router",
|
|
539
|
+
routePath: route.pattern,
|
|
540
|
+
routeType: "render"
|
|
541
|
+
}).catch(() => {});
|
|
542
|
+
try {
|
|
543
|
+
await renderErrorPage(server, req, res, url, pagesDir, 500, void 0, matcher);
|
|
544
|
+
} catch (fallbackErr) {
|
|
545
|
+
res.statusCode = 500;
|
|
546
|
+
res.end(`Internal Server Error: ${fallbackErr.message}`);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
};
|
|
840
551
|
}
|
|
841
552
|
/**
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
553
|
+
* Render a custom error page (404.tsx, 500.tsx, or _error.tsx).
|
|
554
|
+
*
|
|
555
|
+
* Next.js resolution order:
|
|
556
|
+
* - 404: pages/404.tsx -> pages/_error.tsx -> default
|
|
557
|
+
* - 500: pages/500.tsx -> pages/_error.tsx -> default
|
|
558
|
+
* - other: pages/_error.tsx -> default
|
|
559
|
+
*/
|
|
849
560
|
async function renderErrorPage(server, _req, res, url, pagesDir, statusCode, wrapWithRouterContext, fileMatcher) {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
let element;
|
|
889
|
-
if (AppComponent) {
|
|
890
|
-
element = createElement(AppComponent, {
|
|
891
|
-
Component: ErrorComponent,
|
|
892
|
-
pageProps: errorProps,
|
|
893
|
-
});
|
|
894
|
-
}
|
|
895
|
-
else {
|
|
896
|
-
element = createElement(ErrorComponent, errorProps);
|
|
897
|
-
}
|
|
898
|
-
if (wrapFn) {
|
|
899
|
-
element = wrapFn(element);
|
|
900
|
-
}
|
|
901
|
-
const bodyHtml = await renderToStringAsync(element);
|
|
902
|
-
// Try custom _document
|
|
903
|
-
let html;
|
|
904
|
-
let DocumentComponent = null;
|
|
905
|
-
const docPathErr = path.join(pagesDir, "_document");
|
|
906
|
-
if (findFileWithExtensions(docPathErr, matcher)) {
|
|
907
|
-
try {
|
|
908
|
-
const docModule = await server.ssrLoadModule(docPathErr);
|
|
909
|
-
DocumentComponent = docModule.default ?? null;
|
|
910
|
-
}
|
|
911
|
-
catch {
|
|
912
|
-
// _document exists but failed to load
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
if (DocumentComponent) {
|
|
916
|
-
const docElement = createElement(DocumentComponent);
|
|
917
|
-
let docHtml = await renderToStringAsync(docElement);
|
|
918
|
-
docHtml = docHtml.replace("__NEXT_MAIN__", bodyHtml);
|
|
919
|
-
docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", "");
|
|
920
|
-
html = docHtml;
|
|
921
|
-
}
|
|
922
|
-
else {
|
|
923
|
-
html = `<!DOCTYPE html>
|
|
561
|
+
const matcher = fileMatcher ?? createValidFileMatcher();
|
|
562
|
+
const candidates = statusCode === 404 ? ["404", "_error"] : statusCode === 500 ? ["500", "_error"] : ["_error"];
|
|
563
|
+
for (const candidate of candidates) try {
|
|
564
|
+
const candidatePath = path.join(pagesDir, candidate);
|
|
565
|
+
if (!findFileWithExtensions(candidatePath, matcher)) continue;
|
|
566
|
+
const ErrorComponent = (await server.ssrLoadModule(candidatePath)).default;
|
|
567
|
+
if (!ErrorComponent) continue;
|
|
568
|
+
let AppComponent = null;
|
|
569
|
+
const appPathErr = path.join(pagesDir, "_app");
|
|
570
|
+
if (findFileWithExtensions(appPathErr, matcher)) try {
|
|
571
|
+
AppComponent = (await server.ssrLoadModule(appPathErr)).default ?? null;
|
|
572
|
+
} catch {}
|
|
573
|
+
const createElement = React.createElement;
|
|
574
|
+
const errorProps = { statusCode };
|
|
575
|
+
let wrapFn = wrapWithRouterContext;
|
|
576
|
+
if (!wrapFn) try {
|
|
577
|
+
wrapFn = (await server.ssrLoadModule("next/router")).wrapWithRouterContext;
|
|
578
|
+
} catch {}
|
|
579
|
+
let element;
|
|
580
|
+
if (AppComponent) element = createElement(AppComponent, {
|
|
581
|
+
Component: ErrorComponent,
|
|
582
|
+
pageProps: errorProps
|
|
583
|
+
});
|
|
584
|
+
else element = createElement(ErrorComponent, errorProps);
|
|
585
|
+
if (wrapFn) element = wrapFn(element);
|
|
586
|
+
const bodyHtml = await renderToStringAsync(element);
|
|
587
|
+
let html;
|
|
588
|
+
let DocumentComponent = null;
|
|
589
|
+
const docPathErr = path.join(pagesDir, "_document");
|
|
590
|
+
if (findFileWithExtensions(docPathErr, matcher)) try {
|
|
591
|
+
DocumentComponent = (await server.ssrLoadModule(docPathErr)).default ?? null;
|
|
592
|
+
} catch {}
|
|
593
|
+
if (DocumentComponent) {
|
|
594
|
+
let docHtml = await renderToStringAsync(createElement(DocumentComponent));
|
|
595
|
+
docHtml = docHtml.replace("__NEXT_MAIN__", bodyHtml);
|
|
596
|
+
docHtml = docHtml.replace("<!-- __NEXT_SCRIPTS__ -->", "");
|
|
597
|
+
html = docHtml;
|
|
598
|
+
} else html = `<!DOCTYPE html>
|
|
924
599
|
<html>
|
|
925
600
|
<head>
|
|
926
601
|
<meta charset="utf-8" />
|
|
@@ -930,19 +605,17 @@ async function renderErrorPage(server, _req, res, url, pagesDir, statusCode, wra
|
|
|
930
605
|
<div id="__next">${bodyHtml}</div>
|
|
931
606
|
</body>
|
|
932
607
|
</html>`;
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
// No custom error page found — use plain text fallback
|
|
945
|
-
res.writeHead(statusCode, { "Content-Type": "text/plain" });
|
|
946
|
-
res.end(`${statusCode} - ${statusCode === 404 ? "Page not found" : "Internal Server Error"}`);
|
|
608
|
+
const transformedHtml = await server.transformIndexHtml(url, html);
|
|
609
|
+
res.writeHead(statusCode, { "Content-Type": "text/html" });
|
|
610
|
+
res.end(transformedHtml);
|
|
611
|
+
return;
|
|
612
|
+
} catch {
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
res.writeHead(statusCode, { "Content-Type": "text/plain" });
|
|
616
|
+
res.end(`${statusCode} - ${statusCode === 404 ? "Page not found" : "Internal Server Error"}`);
|
|
947
617
|
}
|
|
618
|
+
//#endregion
|
|
619
|
+
export { createSSRHandler, detectLocaleFromHeaders, extractLocaleFromUrl, parseCookieLocale };
|
|
620
|
+
|
|
948
621
|
//# sourceMappingURL=dev-server.js.map
|