From ca6a662a551085b5e1c659f0dd42c2205a16ce17 Mon Sep 17 00:00:00 2001 From: Chris Kerr Date: Wed, 11 Jan 2023 09:50:31 +1000 Subject: [PATCH 01/10] allow access to public env in app.html --- .changeset/spotty-points-battle.md | 5 +++++ .../docs/10-getting-started/30-project-structure.md | 1 + packages/kit/src/exports/vite/dev/index.js | 9 ++++++++- packages/kit/test/apps/basics/src/app.html | 2 ++ packages/kit/test/apps/basics/test/client.test.js | 12 ++++++++++++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changeset/spotty-points-battle.md diff --git a/.changeset/spotty-points-battle.md b/.changeset/spotty-points-battle.md new file mode 100644 index 000000000000..036d33b05d31 --- /dev/null +++ b/.changeset/spotty-points-battle.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +enable access to private env within app.html diff --git a/documentation/docs/10-getting-started/30-project-structure.md b/documentation/docs/10-getting-started/30-project-structure.md index 1a3d9b6724a8..bb2ddb776f82 100644 --- a/documentation/docs/10-getting-started/30-project-structure.md +++ b/documentation/docs/10-getting-started/30-project-structure.md @@ -45,6 +45,7 @@ The `src` directory contains the meat of your project. - `%sveltekit.body%` — the markup for a rendered page. This should live inside a `
` or other element, rather than directly inside ``, to prevent bugs caused by browser extensions injecting elements that are then destroyed by the hydration process. SvelteKit will warn you in development if this is not the case - `%sveltekit.assets%` — either [`paths.assets`](/docs/configuration#paths), if specified, or a relative path to [`paths.base`](/docs/configuration#paths) - `%sveltekit.nonce%` — a [CSP](/docs/configuration#csp) nonce for manually included links and scripts, if used + - `%sveltekit.env.{{env_name}}%` - this will be replaced at render time with public env which matches `{{env_name}}`. It will fallback to `''` if not matched. - `error.html` (optional) is the page that is rendered when everything else fails. It can contain the following placeholders: - `%sveltekit.status%` — the HTTP status - `%sveltekit.error.message%` — the error message diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index f20be5190b6f..7ab4b4f428b6 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -14,7 +14,7 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js'; import * as sync from '../../../core/sync/sync.js'; import { get_mime_lookup, runtime_base } from '../../../core/utils.js'; import { compact } from '../../../utils/array.js'; -import { not_found } from '../utils.js'; +import { get_env, not_found } from '../utils.js'; const cwd = process.cwd(); @@ -42,6 +42,8 @@ export async function dev(vite, vite_config, svelte_config) { sync.init(svelte_config, vite_config.mode); + const publicEnv = get_env(svelte_config.kit.env, vite_config.mode).public; + /** @type {import('types').ManifestData} */ let manifest_data; /** @type {import('types').SSRManifest} */ @@ -465,6 +467,11 @@ export async function dev(vite, vite_config, svelte_config) { return; } + // .replace( + // /%sveltekit\.env\.([^%]+)%/g, + // (_match, capture) => publicEnv[capture] || '' + // ) + const rendered = await server.respond(request, { getClientAddress: () => { const { remoteAddress } = req.socket; diff --git a/packages/kit/test/apps/basics/src/app.html b/packages/kit/test/apps/basics/src/app.html index 4f4316bd9ff4..cf57d8bd0d32 100644 --- a/packages/kit/test/apps/basics/src/app.html +++ b/packages/kit/test/apps/basics/src/app.html @@ -10,5 +10,7 @@
%sveltekit.body%
outside app target +

%sveltekit.env.PUBLIC_STATIC%

+

%sveltekit.env.PRIVATE_STATIC%

diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js index fc547a261841..a763b7447d7a 100644 --- a/packages/kit/test/apps/basics/test/client.test.js +++ b/packages/kit/test/apps/basics/test/client.test.js @@ -1232,3 +1232,15 @@ test.describe('Interactivity', () => { expect(errored).toBe(false); }); }); + +test.describe('env in app.html', () => { + test('can access public env', async ({ page }) => { + await page.goto('/'); + expect(await page.textContent('#public-env-replace')).toBeTruthy(); + }); + + test('cannot access private env', async ({ page }) => { + await page.goto('/'); + expect(await page.textContent('#private-env-replace')).toBeFalsy(); + }); +}); From ac3483f6767d17d32ca8c302cde8f5f1f88cd23c Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Wed, 11 Jan 2023 14:12:16 -0800 Subject: [PATCH 02/10] Update .changeset/spotty-points-battle.md Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> --- .changeset/spotty-points-battle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/spotty-points-battle.md b/.changeset/spotty-points-battle.md index 036d33b05d31..0ca78b9723d0 100644 --- a/.changeset/spotty-points-battle.md +++ b/.changeset/spotty-points-battle.md @@ -2,4 +2,4 @@ '@sveltejs/kit': patch --- -enable access to private env within app.html +feat: enable access to public env within app.html From 2315698e4a6cccf409d49d07a66f24aec9c6f048 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Wed, 11 Jan 2023 14:12:22 -0800 Subject: [PATCH 03/10] Update .changeset/spotty-points-battle.md Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> --- .changeset/spotty-points-battle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/spotty-points-battle.md b/.changeset/spotty-points-battle.md index 0ca78b9723d0..530627587b96 100644 --- a/.changeset/spotty-points-battle.md +++ b/.changeset/spotty-points-battle.md @@ -1,5 +1,5 @@ --- -'@sveltejs/kit': patch +'@sveltejs/kit': minor --- feat: enable access to public env within app.html From 967e1ceb5cb248ce9d6401a748b27ef9eaf81de1 Mon Sep 17 00:00:00 2001 From: Chris Kerr Date: Sat, 14 Jan 2023 13:59:26 +1000 Subject: [PATCH 04/10] updated to match recent changes --- packages/kit/src/core/sync/sync.js | 12 +++++++----- packages/kit/src/core/sync/write_server.js | 18 ++++++++++++------ packages/kit/src/exports/vite/dev/index.js | 16 +++++----------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/packages/kit/src/core/sync/sync.js b/packages/kit/src/core/sync/sync.js index c598607daa54..549528a8c6b8 100644 --- a/packages/kit/src/core/sync/sync.js +++ b/packages/kit/src/core/sync/sync.js @@ -21,14 +21,15 @@ export function init(config, mode) { /** * Update SvelteKit's generated files * @param {import('types').ValidatedConfig} config + * * @param {string} mode */ -export async function create(config) { +export async function create(config, mode) { const manifest_data = create_manifest_data({ config }); const output = path.join(config.kit.outDir, 'generated'); write_client_manifest(config, manifest_data, output); - write_server(config, output); + write_server(config, output, mode); write_root(manifest_data, output); write_matchers(manifest_data, output); await write_all_types(config, manifest_data); @@ -57,13 +58,14 @@ export async function update(config, manifest_data, file) { */ export async function all(config, mode) { init(config, mode); - return await create(config); + return await create(config, mode); } /** * Regenerate server-internal.js in response to src/{app.html,error.html,service-worker.js} changing * @param {import('types').ValidatedConfig} config + * @param {string} mode */ -export function server(config) { - write_server(config, path.join(config.kit.outDir, 'generated')); +export function server(config, mode) { + write_server(config, path.join(config.kit.outDir, 'generated'), mode); } diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index 162a6efc1944..1cf087aa7c2e 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -1,5 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; +import { get_env } from '../../exports/vite/utils.js'; import { posixify, resolve_entry } from '../../utils/filesystem.js'; import { s } from '../../utils/misc.js'; import { load_error_page, load_template } from '../config/index.js'; @@ -13,6 +14,7 @@ import { runtime_directory } from '../utils.js'; * runtime_directory: string; * template: string; * error_page: string; + * public_env: Record; * }} opts */ const server_template = ({ @@ -21,7 +23,8 @@ const server_template = ({ has_service_worker, runtime_directory, template, - error_page + error_page, + public_env }) => ` import root from './root.svelte'; import { set_building, set_paths, set_version } from '${runtime_directory}/shared.js'; @@ -39,10 +42,11 @@ export const options = { service_worker: ${has_service_worker}, templates: { app: ({ head, body, assets, nonce }) => ${s(template) - .replace('%sveltekit.head%', '" + head + "') - .replace('%sveltekit.body%', '" + body + "') + .replace(/%sveltekit\.env\.([^%]+)%/g, (_match, capture) => public_env[capture] || '') .replace(/%sveltekit\.assets%/g, '" + assets + "') - .replace(/%sveltekit\.nonce%/g, '" + nonce + "')}, + .replace(/%sveltekit\.nonce%/g, '" + nonce + "') + .replace('%sveltekit.head%', '" + head + "') + .replace('%sveltekit.body%', '" + body + "')}, error: ({ status, message }) => ${s(error_page) .replace(/%sveltekit\.status%/g, '" + status + "') .replace(/%sveltekit\.error\.message%/g, '" + message + "')} @@ -64,8 +68,9 @@ export { set_building, set_paths }; * Write server configuration to disk * @param {import('types').ValidatedConfig} config * @param {string} output + * @param {string} mode */ -export function write_server(config, output) { +export function write_server(config, output, mode) { // TODO the casting shouldn't be necessary — investigate const hooks_file = /** @type {string} */ (resolve_entry(config.kit.files.hooks.server)); @@ -83,7 +88,8 @@ export function write_server(config, output) { config.kit.serviceWorker.register && !!resolve_entry(config.kit.files.serviceWorker), runtime_directory: relative(runtime_directory), template: load_template(process.cwd(), config), - error_page: load_error_page(config) + error_page: load_error_page(config), + public_env: get_env(config.kit.env, mode).public }) ); } diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 7ab4b4f428b6..fa020ba97167 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -14,7 +14,7 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js'; import * as sync from '../../../core/sync/sync.js'; import { get_mime_lookup, runtime_base } from '../../../core/utils.js'; import { compact } from '../../../utils/array.js'; -import { get_env, not_found } from '../utils.js'; +import { not_found } from '../utils.js'; const cwd = process.cwd(); @@ -40,9 +40,8 @@ export async function dev(vite, vite_config, svelte_config) { return fetch(info, init); }; - sync.init(svelte_config, vite_config.mode); - - const publicEnv = get_env(svelte_config.kit.env, vite_config.mode).public; + const mode = vite_config.mode; + sync.init(svelte_config, mode); /** @type {import('types').ManifestData} */ let manifest_data; @@ -66,7 +65,7 @@ export async function dev(vite, vite_config, svelte_config) { async function update_manifest() { try { - ({ manifest_data } = await sync.create(svelte_config)); + ({ manifest_data } = await sync.create(svelte_config, mode)); if (manifest_error) { manifest_error = null; @@ -292,7 +291,7 @@ export async function dev(vite, vite_config, svelte_config) { file.startsWith(serviceWorker) || file.startsWith(hooks.server) ) { - sync.server(svelte_config); + sync.server(svelte_config, mode); } }); @@ -467,11 +466,6 @@ export async function dev(vite, vite_config, svelte_config) { return; } - // .replace( - // /%sveltekit\.env\.([^%]+)%/g, - // (_match, capture) => publicEnv[capture] || '' - // ) - const rendered = await server.respond(request, { getClientAddress: () => { const { remoteAddress } = req.socket; From 56431ec7d476a4ecead7b14597c0515045e50d8a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 19 Jan 2023 17:20:28 -0500 Subject: [PATCH 05/10] don't silently fail when encountering private env vars --- packages/kit/src/core/config/index.js | 39 ++++++++++++------- packages/kit/src/exports/vite/dev/index.js | 6 +-- packages/kit/test/apps/basics/src/app.html | 1 - .../kit/test/apps/basics/test/client.test.js | 5 --- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js index 047c67532b47..04a4eaffc0f3 100644 --- a/packages/kit/src/core/config/index.js +++ b/packages/kit/src/core/config/index.js @@ -9,24 +9,33 @@ import options from './options.js'; * @param {string} cwd * @param {import('types').ValidatedConfig} config */ -export function load_template(cwd, config) { - const { appTemplate } = config.kit.files; - const relative = path.relative(cwd, appTemplate); - - if (fs.existsSync(appTemplate)) { - const contents = fs.readFileSync(appTemplate, 'utf8'); - - const expected_tags = ['%sveltekit.head%', '%sveltekit.body%']; - expected_tags.forEach((tag) => { - if (contents.indexOf(tag) === -1) { - throw new Error(`${relative} is missing ${tag}`); - } - }); - } else { +export function load_template(cwd, { kit }) { + const { env, files } = kit; + + const relative = path.relative(cwd, files.appTemplate); + + if (!fs.existsSync(files.appTemplate)) { throw new Error(`${relative} does not exist`); } - return fs.readFileSync(appTemplate, 'utf-8'); + const contents = fs.readFileSync(files.appTemplate, 'utf8'); + + const expected_tags = ['%sveltekit.head%', '%sveltekit.body%']; + expected_tags.forEach((tag) => { + if (contents.indexOf(tag) === -1) { + throw new Error(`${relative} is missing ${tag}`); + } + }); + + for (const match of contents.matchAll(/%sveltekit\.env\.([^%]+)%/g)) { + if (!match[1].startsWith(env.publicPrefix)) { + throw new Error( + `Environment variables in ${relative} must start with ${env.publicPrefix} (saw %sveltekit.env.${match[1]}%)` + ); + } + } + + return contents; } /** diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 369f080b185a..33e4de12a4ff 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -74,8 +74,7 @@ export async function dev(vite, vite_config, svelte_config) { } catch (error) { manifest_error = /** @type {Error} */ (error); - console.error(colors.bold().red('Invalid routes')); - console.error(error); + console.error(colors.bold().red(manifest_error.message)); vite.ws.send({ type: 'error', err: { @@ -445,8 +444,7 @@ export async function dev(vite, vite_config, svelte_config) { } if (manifest_error) { - console.error(colors.bold().red('Invalid routes')); - console.error(manifest_error); + console.error(colors.bold().red(manifest_error.message)); const error_page = load_error_page(svelte_config); diff --git a/packages/kit/test/apps/basics/src/app.html b/packages/kit/test/apps/basics/src/app.html index cf57d8bd0d32..b1903856dd98 100644 --- a/packages/kit/test/apps/basics/src/app.html +++ b/packages/kit/test/apps/basics/src/app.html @@ -11,6 +11,5 @@
%sveltekit.body%
outside app target

%sveltekit.env.PUBLIC_STATIC%

-

%sveltekit.env.PRIVATE_STATIC%

diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js index 5c3e94f7fe02..3f119be8a19c 100644 --- a/packages/kit/test/apps/basics/test/client.test.js +++ b/packages/kit/test/apps/basics/test/client.test.js @@ -606,9 +606,4 @@ test.describe('env in app.html', () => { await page.goto('/'); expect(await page.textContent('#public-env-replace')).toBeTruthy(); }); - - test('cannot access private env', async ({ page }) => { - await page.goto('/'); - expect(await page.textContent('#private-env-replace')).toBeFalsy(); - }); }); From ea249c65905eaa76808c2b60515c783de8e5d257 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 19 Jan 2023 17:25:46 -0500 Subject: [PATCH 06/10] replace vars at run time, not build time --- packages/kit/src/core/sync/sync.js | 12 +++++------- packages/kit/src/core/sync/write_server.js | 18 ++++++++---------- packages/kit/src/exports/vite/dev/index.js | 4 ++-- packages/kit/src/runtime/env-public.js | 1 + packages/kit/src/runtime/server/page/render.js | 3 ++- packages/kit/types/internal.d.ts | 8 +++++++- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/packages/kit/src/core/sync/sync.js b/packages/kit/src/core/sync/sync.js index 2b38ca2c13d0..d99c3315adc3 100644 --- a/packages/kit/src/core/sync/sync.js +++ b/packages/kit/src/core/sync/sync.js @@ -21,15 +21,14 @@ export function init(config, mode) { /** * Update SvelteKit's generated files * @param {import('types').ValidatedConfig} config - * * @param {string} mode */ -export async function create(config, mode) { +export async function create(config) { const manifest_data = create_manifest_data({ config }); const output = path.join(config.kit.outDir, 'generated'); write_client_manifest(config, manifest_data, output); - write_server(config, output, mode); + write_server(config, output); write_root(manifest_data, output); write_matchers(manifest_data, output); await write_all_types(config, manifest_data); @@ -58,7 +57,7 @@ export async function update(config, manifest_data, file) { */ export async function all(config, mode) { init(config, mode); - return await create(config, mode); + return await create(config); } /** @@ -75,8 +74,7 @@ export async function all_types(config, mode) { /** * Regenerate server-internal.js in response to src/{app.html,error.html,service-worker.js} changing * @param {import('types').ValidatedConfig} config - * @param {string} mode */ -export function server(config, mode) { - write_server(config, path.join(config.kit.outDir, 'generated'), mode); +export function server(config) { + write_server(config, path.join(config.kit.outDir, 'generated')); } diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index 1cf087aa7c2e..2e02a38dc7bc 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -1,6 +1,5 @@ import fs from 'node:fs'; import path from 'node:path'; -import { get_env } from '../../exports/vite/utils.js'; import { posixify, resolve_entry } from '../../utils/filesystem.js'; import { s } from '../../utils/misc.js'; import { load_error_page, load_template } from '../config/index.js'; @@ -14,7 +13,6 @@ import { runtime_directory } from '../utils.js'; * runtime_directory: string; * template: string; * error_page: string; - * public_env: Record; * }} opts */ const server_template = ({ @@ -23,8 +21,7 @@ const server_template = ({ has_service_worker, runtime_directory, template, - error_page, - public_env + error_page }) => ` import root from './root.svelte'; import { set_building, set_paths, set_version } from '${runtime_directory}/shared.js'; @@ -41,8 +38,11 @@ export const options = { root, service_worker: ${has_service_worker}, templates: { - app: ({ head, body, assets, nonce }) => ${s(template) - .replace(/%sveltekit\.env\.([^%]+)%/g, (_match, capture) => public_env[capture] || '') + app: ({ head, body, assets, nonce, env }) => ${s(template) + .replace( + /%sveltekit\.env\.([^%]+)%/g, + (_match, capture) => `" + (env[${s(capture)}] ?? "") + "` + ) .replace(/%sveltekit\.assets%/g, '" + assets + "') .replace(/%sveltekit\.nonce%/g, '" + nonce + "') .replace('%sveltekit.head%', '" + head + "') @@ -68,9 +68,8 @@ export { set_building, set_paths }; * Write server configuration to disk * @param {import('types').ValidatedConfig} config * @param {string} output - * @param {string} mode */ -export function write_server(config, output, mode) { +export function write_server(config, output) { // TODO the casting shouldn't be necessary — investigate const hooks_file = /** @type {string} */ (resolve_entry(config.kit.files.hooks.server)); @@ -88,8 +87,7 @@ export function write_server(config, output, mode) { config.kit.serviceWorker.register && !!resolve_entry(config.kit.files.serviceWorker), runtime_directory: relative(runtime_directory), template: load_template(process.cwd(), config), - error_page: load_error_page(config), - public_env: get_env(config.kit.env, mode).public + error_page: load_error_page(config) }) ); } diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 33e4de12a4ff..71f0b70b775f 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -65,7 +65,7 @@ export async function dev(vite, vite_config, svelte_config) { async function update_manifest() { try { - ({ manifest_data } = await sync.create(svelte_config, mode)); + ({ manifest_data } = await sync.create(svelte_config)); if (manifest_error) { manifest_error = null; @@ -290,7 +290,7 @@ export async function dev(vite, vite_config, svelte_config) { file.startsWith(serviceWorker) || file.startsWith(hooks.server) ) { - sync.server(svelte_config, mode); + sync.server(svelte_config); } }); diff --git a/packages/kit/src/runtime/env-public.js b/packages/kit/src/runtime/env-public.js index 481a87046093..800f6262aea6 100644 --- a/packages/kit/src/runtime/env-public.js +++ b/packages/kit/src/runtime/env-public.js @@ -1,3 +1,4 @@ +/** @type {Record} */ export let env = {}; /** @type {(environment: Record) => void} */ diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 85f06742b2d9..e23e8ee006b0 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -366,7 +366,8 @@ export async function render_response({ head, body, assets: resolved_assets, - nonce: /** @type {string} */ (csp.nonce) + nonce: /** @type {string} */ (csp.nonce), + env }); // TODO flush chunks as early as we can diff --git a/packages/kit/types/internal.d.ts b/packages/kit/types/internal.d.ts index 54679a608683..85734650ff7f 100644 --- a/packages/kit/types/internal.d.ts +++ b/packages/kit/types/internal.d.ts @@ -306,7 +306,13 @@ export interface SSROptions { root: SSRComponent['default']; service_worker: boolean; templates: { - app(values: { head: string; body: string; assets: string; nonce: string }): string; + app(values: { + head: string; + body: string; + assets: string; + nonce: string; + env: Record; + }): string; error(values: { message: string; status: number }): string; }; } From 77851fe3fdc8e541b879230724fa5a1c6e76a3ad Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 19 Jan 2023 17:30:02 -0500 Subject: [PATCH 07/10] remove

as it was interfering with other tests --- packages/kit/test/apps/basics/.env | 2 ++ packages/kit/test/apps/basics/src/app.html | 3 +-- packages/kit/test/apps/basics/test/client.test.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/kit/test/apps/basics/.env b/packages/kit/test/apps/basics/.env index 1597af1243ec..a406fc2451a1 100644 --- a/packages/kit/test/apps/basics/.env +++ b/packages/kit/test/apps/basics/.env @@ -3,3 +3,5 @@ PRIVATE_DYNAMIC="accessible to server-side code/evaluated at run time" PUBLIC_STATIC="accessible anywhere/replaced at build time" PUBLIC_DYNAMIC="accessible anywhere/evaluated at run time" + +PUBLIC_THEME="groovy" diff --git a/packages/kit/test/apps/basics/src/app.html b/packages/kit/test/apps/basics/src/app.html index b1903856dd98..aa17593fe727 100644 --- a/packages/kit/test/apps/basics/src/app.html +++ b/packages/kit/test/apps/basics/src/app.html @@ -7,9 +7,8 @@ %sveltekit.head% - +

%sveltekit.body%
outside app target -

%sveltekit.env.PUBLIC_STATIC%

diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js index 3f119be8a19c..91b4beec802a 100644 --- a/packages/kit/test/apps/basics/test/client.test.js +++ b/packages/kit/test/apps/basics/test/client.test.js @@ -604,6 +604,6 @@ test.describe('Content negotiation', () => { test.describe('env in app.html', () => { test('can access public env', async ({ page }) => { await page.goto('/'); - expect(await page.textContent('#public-env-replace')).toBeTruthy(); + expect(await page.locator('body').getAttribute('class')).toContain('groovy'); }); }); From b449423ec4f4cff710d3114792c9e0ada343e561 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 19 Jan 2023 17:31:30 -0500 Subject: [PATCH 08/10] reduce diff --- packages/kit/src/exports/vite/dev/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 71f0b70b775f..a2ba0d881a2c 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -40,8 +40,7 @@ export async function dev(vite, vite_config, svelte_config) { return fetch(info, init); }; - const mode = vite_config.mode; - sync.init(svelte_config, mode); + sync.init(svelte_config, vite_config.mode); /** @type {import('types').ManifestData} */ let manifest_data; From bba3c8390e855882f5869893840dad557b007dcb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 19 Jan 2023 17:33:22 -0500 Subject: [PATCH 09/10] reduce diff --- packages/kit/src/core/sync/write_server.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index 2e02a38dc7bc..6cb05a8ee626 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -39,14 +39,14 @@ export const options = { service_worker: ${has_service_worker}, templates: { app: ({ head, body, assets, nonce, env }) => ${s(template) + .replace('%sveltekit.head%', '" + head + "') + .replace('%sveltekit.body%', '" + body + "') + .replace(/%sveltekit\.assets%/g, '" + assets + "') + .replace(/%sveltekit\.nonce%/g, '" + nonce + "') .replace( /%sveltekit\.env\.([^%]+)%/g, (_match, capture) => `" + (env[${s(capture)}] ?? "") + "` - ) - .replace(/%sveltekit\.assets%/g, '" + assets + "') - .replace(/%sveltekit\.nonce%/g, '" + nonce + "') - .replace('%sveltekit.head%', '" + head + "') - .replace('%sveltekit.body%', '" + body + "')}, + )}, error: ({ status, message }) => ${s(error_page) .replace(/%sveltekit\.status%/g, '" + status + "') .replace(/%sveltekit\.error\.message%/g, '" + message + "')} From 30b353b908d6dcee89be329b6b73190f9a84e6d7 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 19 Jan 2023 17:42:27 -0500 Subject: [PATCH 10/10] tweak docs --- documentation/docs/10-getting-started/30-project-structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/10-getting-started/30-project-structure.md b/documentation/docs/10-getting-started/30-project-structure.md index bb2ddb776f82..c75a46eb46d0 100644 --- a/documentation/docs/10-getting-started/30-project-structure.md +++ b/documentation/docs/10-getting-started/30-project-structure.md @@ -45,7 +45,7 @@ The `src` directory contains the meat of your project. - `%sveltekit.body%` — the markup for a rendered page. This should live inside a `
` or other element, rather than directly inside ``, to prevent bugs caused by browser extensions injecting elements that are then destroyed by the hydration process. SvelteKit will warn you in development if this is not the case - `%sveltekit.assets%` — either [`paths.assets`](/docs/configuration#paths), if specified, or a relative path to [`paths.base`](/docs/configuration#paths) - `%sveltekit.nonce%` — a [CSP](/docs/configuration#csp) nonce for manually included links and scripts, if used - - `%sveltekit.env.{{env_name}}%` - this will be replaced at render time with public env which matches `{{env_name}}`. It will fallback to `''` if not matched. + - `%sveltekit.env.[NAME]%` - this will be replaced at render time with the `[NAME]` environment variable, which must begin with the [`publicPrefix`](https://kit.svelte.dev/docs/configuration#env) (usually `PUBLIC_`). It will fallback to `''` if not matched. - `error.html` (optional) is the page that is rendered when everything else fails. It can contain the following placeholders: - `%sveltekit.status%` — the HTTP status - `%sveltekit.error.message%` — the error message