From ebe2bd2eeb3f214481c31da28a080a812662fcc0 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Thu, 14 Aug 2025 18:40:48 +0200 Subject: [PATCH 1/5] fix: load env before prerender --- packages/kit/src/core/postbuild/prerender.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/core/postbuild/prerender.js b/packages/kit/src/core/postbuild/prerender.js index ad15ccb561dc..687a131ec52b 100644 --- a/packages/kit/src/core/postbuild/prerender.js +++ b/packages/kit/src/core/postbuild/prerender.js @@ -15,6 +15,7 @@ import * as devalue from 'devalue'; import { createReadableStream } from '@sveltejs/kit/node'; import generate_fallback from './fallback.js'; import { stringify_remote_arg } from '../../runtime/shared.js'; +import { filter_private_env, filter_public_env } from '../../utils/env.js'; export default forked(import.meta.url, prerender); @@ -44,10 +45,24 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) { /** @type {import('types').ServerModule} */ const { Server } = await import(pathToFileURL(`${out}/server/index.js`).href); + /** @type {import('types').ValidatedKitConfig} */ + const config = (await load_config()).kit; + + const server_root = join(config.outDir, 'output'); + // configure `import { building } from '$app/environment'` — // essential we do this before analysing the code internal.set_building(); internal.set_prerendering(); + const { publicPrefix: public_prefix, privatePrefix: private_prefix } = config.env; + const private_env = filter_private_env(env, { public_prefix, private_prefix }); + const public_env = filter_public_env(env, { public_prefix, private_prefix }); + + internal.set_private_env(private_env); + internal.set_public_env(public_env); + internal.set_safe_public_env(public_env); + internal.set_manifest(manifest); + internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`)); /** * @template {{message: string}} T @@ -98,9 +113,6 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) { /** @type {Set} */ const prerendered_routes = new Set(); - /** @type {import('types').ValidatedKitConfig} */ - const config = (await load_config()).kit; - if (hash) { const fallback = await generate_fallback({ manifest_path, From 823711692380a545280ef4328e96fa89c78cec31 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Thu, 14 Aug 2025 18:47:39 +0200 Subject: [PATCH 2/5] chore: changeset --- .changeset/wide-cobras-yell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wide-cobras-yell.md diff --git a/.changeset/wide-cobras-yell.md b/.changeset/wide-cobras-yell.md new file mode 100644 index 000000000000..65a101734b88 --- /dev/null +++ b/.changeset/wide-cobras-yell.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: load env before prerender From 0bb7db9dceb9d545376af008d0dcebd9d55a4828 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Thu, 14 Aug 2025 18:59:24 +0200 Subject: [PATCH 3/5] chore: add test --- .../apps/basics/src/routes/remote/accessing-env.remote.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js diff --git a/packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js b/packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js new file mode 100644 index 000000000000..749293ce26a8 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js @@ -0,0 +1,6 @@ +import { env } from '$env/dynamic/private'; +import { env as public_env } from '$env/dynamic/public'; + +if (!env.PRIVATE_DYNAMIC || !public_env.PUBLIC_DYNAMIC) { + throw new Error('Dynamic environment variables are not set up correctly'); +} From 6bd6e0be9cc90f353d1c41db958bc811c53df6a9 Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Fri, 15 Aug 2025 10:09:03 +0200 Subject: [PATCH 4/5] chore: add comment in test file Co-authored-by: Rich Harris --- .../test/apps/basics/src/routes/remote/accessing-env.remote.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js b/packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js index 749293ce26a8..430d6f1af775 100644 --- a/packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js +++ b/packages/kit/test/apps/basics/src/routes/remote/accessing-env.remote.js @@ -2,5 +2,7 @@ import { env } from '$env/dynamic/private'; import { env as public_env } from '$env/dynamic/public'; if (!env.PRIVATE_DYNAMIC || !public_env.PUBLIC_DYNAMIC) { + // This checks that dynamic env vars are available when prerendering remote functions + // https://github.com/sveltejs/kit/pull/14219 throw new Error('Dynamic environment variables are not set up correctly'); } From b2d1de4031356dfabf85646f81a3d0b5d1ec3bf6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 19 Aug 2025 17:33:34 -0400 Subject: [PATCH 5/5] simplify --- packages/kit/src/core/postbuild/prerender.js | 30 ++++++-------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/packages/kit/src/core/postbuild/prerender.js b/packages/kit/src/core/postbuild/prerender.js index a3335b844a30..0e0b2e9b653a 100644 --- a/packages/kit/src/core/postbuild/prerender.js +++ b/packages/kit/src/core/postbuild/prerender.js @@ -15,7 +15,6 @@ import * as devalue from 'devalue'; import { createReadableStream } from '@sveltejs/kit/node'; import generate_fallback from './fallback.js'; import { stringify_remote_arg } from '../../runtime/shared.js'; -import { filter_private_env, filter_public_env } from '../../utils/env.js'; export default forked(import.meta.url, prerender); @@ -45,24 +44,10 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) { /** @type {import('types').ServerModule} */ const { Server } = await import(pathToFileURL(`${out}/server/index.js`).href); - /** @type {import('types').ValidatedKitConfig} */ - const config = (await load_config()).kit; - - const server_root = join(config.outDir, 'output'); - // configure `import { building } from '$app/environment'` — // essential we do this before analysing the code internal.set_building(); internal.set_prerendering(); - const { publicPrefix: public_prefix, privatePrefix: private_prefix } = config.env; - const private_env = filter_private_env(env, { public_prefix, private_prefix }); - const public_env = filter_public_env(env, { public_prefix, private_prefix }); - - internal.set_private_env(private_env); - internal.set_public_env(public_env); - internal.set_safe_public_env(public_env); - internal.set_manifest(manifest); - internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`)); /** * @template {{message: string}} T @@ -113,6 +98,9 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) { /** @type {Set} */ const prerendered_routes = new Set(); + /** @type {import('types').ValidatedKitConfig} */ + const config = (await load_config()).kit; + if (hash) { const fallback = await generate_fallback({ manifest_path, @@ -137,6 +125,12 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) { installPolyfills(); + const server = new Server(manifest); + await server.init({ + env, + read: (file) => createReadableStream(`${config.outDir}/output/server/${file}`) + }); + /** @type {Map} */ const saved = new Map(); @@ -515,12 +509,6 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) { log.info('Prerendering'); - const server = new Server(manifest); - await server.init({ - env, - read: (file) => createReadableStream(`${config.outDir}/output/server/${file}`) - }); - for (const entry of config.prerender.entries) { if (entry === '*') { for (const [id, prerender] of prerender_map) {