@sveltejs/kit 2.17.1 → 2.17.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "2.17.1",
3
+ "version": "2.17.3",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -330,7 +330,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
330
330
  /** @type {Set<string>} */ (expected_hashlinks.get(key)).add(decoded);
331
331
  }
332
332
 
333
- enqueue(decoded, decode_uri(pathname), pathname);
333
+ void enqueue(decoded, decode_uri(pathname), pathname);
334
334
  }
335
335
  }
336
336
  }
@@ -366,7 +366,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
366
366
  if (location) {
367
367
  const resolved = resolve(encoded, location);
368
368
  if (is_root_relative(resolved)) {
369
- enqueue(decoded, decode_uri(resolved), resolved);
369
+ void enqueue(decoded, decode_uri(resolved), resolved);
370
370
  }
371
371
 
372
372
  if (!headers['x-sveltekit-normalize']) {
@@ -485,17 +485,17 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
485
485
 
486
486
  if (processed_id.includes('[')) continue;
487
487
  const path = `/${get_route_segments(processed_id).join('/')}`;
488
- enqueue(null, config.paths.base + path);
488
+ void enqueue(null, config.paths.base + path);
489
489
  }
490
490
  }
491
491
  } else {
492
- enqueue(null, config.paths.base + entry);
492
+ void enqueue(null, config.paths.base + entry);
493
493
  }
494
494
  }
495
495
 
496
496
  for (const { id, entries } of route_level_entries) {
497
497
  for (const entry of entries) {
498
- enqueue(null, config.paths.base + entry, undefined, id);
498
+ void enqueue(null, config.paths.base + entry, undefined, id);
499
499
  }
500
500
  }
501
501
 
@@ -13,6 +13,7 @@ export function queue(concurrency) {
13
13
 
14
14
  let current = 0;
15
15
 
16
+ // TODO: Whenever Node >21 is minimum supported version, we can use `Promise.withResolvers` to avoid this ceremony
16
17
  /** @type {(value?: any) => void} */
17
18
  let fulfil;
18
19
 
@@ -39,7 +40,7 @@ export function queue(concurrency) {
39
40
  current += 1;
40
41
  const promise = Promise.resolve(task.fn());
41
42
 
42
- promise
43
+ void promise
43
44
  .then(task.fulfil, (err) => {
44
45
  task.reject(err);
45
46
  reject(err);
@@ -26,7 +26,7 @@ function get_raw_body(req, body_size_limit) {
26
26
 
27
27
  if (req.destroyed) {
28
28
  const readable = new ReadableStream();
29
- readable.cancel();
29
+ void readable.cancel();
30
30
  return readable;
31
31
  }
32
32
 
@@ -176,7 +176,7 @@ export async function setResponse(res, response) {
176
176
  const reader = response.body.getReader();
177
177
 
178
178
  if (res.destroyed) {
179
- reader.cancel();
179
+ void reader.cancel();
180
180
  return;
181
181
  }
182
182
 
@@ -193,7 +193,7 @@ export async function setResponse(res, response) {
193
193
  res.on('close', cancel);
194
194
  res.on('error', cancel);
195
195
 
196
- next();
196
+ void next();
197
197
  async function next() {
198
198
  try {
199
199
  for (;;) {
@@ -1484,7 +1484,7 @@ export type SubmitFunction<
1484
1484
  * @param invalidateAll Set `invalidateAll: false` if you don't want the action to call `invalidateAll` after submission.
1485
1485
  */
1486
1486
  update: (options?: { reset?: boolean; invalidateAll?: boolean }) => Promise<void>;
1487
- }) => void)
1487
+ }) => MaybePromise<void>)
1488
1488
  >;
1489
1489
 
1490
1490
  /**
@@ -25,45 +25,52 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
25
25
  /** @type {Set<string>} */
26
26
  const client_stylesheets = new Set();
27
27
  for (const key in client_manifest) {
28
- const file = client_manifest[key];
29
- if (file.css?.[0]) {
30
- client_stylesheets.add(file.css[0]);
31
- }
28
+ client_manifest[key].css?.forEach((filename) => {
29
+ client_stylesheets.add(filename);
30
+ });
32
31
  }
33
32
 
34
- /** @type {Map<number, string>} */
33
+ /** @type {Map<number, string[]>} */
35
34
  const server_stylesheets = new Map();
35
+ manifest_data.nodes.forEach((node, i) => {
36
+ if (!node.component || !server_manifest[node.component]) return;
36
37
 
37
- const component_stylesheet_map = new Map(Object.values(server_manifest).map((file) => [file.src, file.css?.[0]]));
38
+ const { stylesheets } = find_deps(server_manifest, node.component, false);
38
39
 
39
- manifest_data.nodes.forEach((node, i) => {
40
- const server_stylesheet = component_stylesheet_map.get(node.component);
41
- if (node.component && server_stylesheet) {
42
- server_stylesheets.set(i, server_stylesheet);
40
+ if (stylesheets.length) {
41
+ server_stylesheets.set(i, stylesheets);
43
42
  }
44
43
  });
45
44
 
46
- // ignore dynamically imported stylesheets since we can't inline those
47
- css.filter(asset => client_stylesheets.has(asset.fileName))
48
- .forEach((asset) => {
49
- if (asset.source.length < kit.inlineStyleThreshold) {
50
- // We know that the names for entry points are numbers.
51
- const [index] = basename(asset.fileName).split('.');
52
- // There can also be other CSS files from shared components
53
- // for example, which we need to ignore here.
54
- if (isNaN(+index)) return;
55
-
56
- const server_stylesheet = server_stylesheets.get(+index);
57
- const file = `${out}/server/stylesheets/${index}.js`;
58
-
59
- // we need to inline the server stylesheet instead of the client one
60
- // so that asset paths are correct on document load
61
- const source = fs.readFileSync(`${out}/server/${server_stylesheet}`, 'utf-8');
62
-
63
- fs.writeFileSync(file, `// ${server_stylesheet}\nexport default ${s(source)};`);
64
- stylesheet_lookup.set(asset.fileName, index);
65
- }
45
+ for (const asset of css) {
46
+ // ignore dynamically imported stylesheets since we don't need to inline those
47
+ if (!client_stylesheets.has(asset.fileName) || asset.source.length >= kit.inlineStyleThreshold) {
48
+ continue;
49
+ }
50
+
51
+ // We know that the names for entry points are numbers.
52
+ const [index] = basename(asset.fileName).split('.');
53
+ // There can also be other CSS files from shared components
54
+ // for example, which we need to ignore here.
55
+ if (isNaN(+index)) continue;
56
+
57
+ const file = `${out}/server/stylesheets/${index}.js`;
58
+
59
+ // we need to inline the server stylesheet instead of the client one
60
+ // so that asset paths are correct on document load
61
+ const filenames = server_stylesheets.get(+index);
62
+
63
+ if (!filenames) {
64
+ throw new Error('This should never happen, but if it does, it means we failed to find the server stylesheet for a node.');
65
+ }
66
+
67
+ const sources = filenames.map((filename) => {
68
+ return fs.readFileSync(`${out}/server/${filename}`, 'utf-8');
66
69
  });
70
+ fs.writeFileSync(file, `// ${filenames.join(', ')}\nexport default ${s(sources.join('\n'))};`);
71
+
72
+ stylesheet_lookup.set(asset.fileName, index);
73
+ }
67
74
  }
68
75
 
69
76
  manifest_data.nodes.forEach((node, i) => {
@@ -145,6 +145,7 @@ export async function dev(vite, vite_config, svelte_config) {
145
145
  return `${svelte_config.kit.paths.base}${to_fs(svelte_config.kit.outDir)}/generated/client/nodes/${i}.js`;
146
146
  }
147
147
  }),
148
+ // `css` is not necessary in dev, as the JS file from `nodes` will reference the CSS file
148
149
  routes:
149
150
  svelte_config.kit.router.resolution === 'client'
150
151
  ? undefined
@@ -375,11 +376,11 @@ export async function dev(vite, vite_config, svelte_config) {
375
376
  // changing the svelte config requires restarting the dev server
376
377
  // the config is only read on start and passed on to vite-plugin-svelte
377
378
  // which needs up-to-date values to operate correctly
378
- vite.watcher.on('change', (file) => {
379
+ vite.watcher.on('change', async (file) => {
379
380
  if (path.basename(file) === 'svelte.config.js') {
380
381
  console.log(`svelte config changed, restarting vite dev-server. changed file: ${file}`);
381
382
  restarting = true;
382
- vite.restart();
383
+ await vite.restart();
383
384
  }
384
385
  });
385
386
 
@@ -408,14 +409,14 @@ export async function dev(vite, vite_config, svelte_config) {
408
409
  SvelteKitError: control_module_vite.SvelteKitError
409
410
  });
410
411
  }
411
- align_exports();
412
+ await align_exports();
412
413
  const ws_send = vite.ws.send;
413
414
  /** @param {any} args */
414
415
  vite.ws.send = function (...args) {
415
416
  // We need to reapply the patch after Vite did dependency optimizations
416
417
  // because that clears the module resolutions
417
418
  if (args[0]?.type === 'full-reload' && args[0].path === '*') {
418
- align_exports();
419
+ void align_exports();
419
420
  }
420
421
  return ws_send.apply(vite.ws, args);
421
422
  };
@@ -568,10 +569,10 @@ export async function dev(vite, vite_config, svelte_config) {
568
569
  if (rendered.status === 404) {
569
570
  // @ts-expect-error
570
571
  serve_static_middleware.handle(req, res, () => {
571
- setResponse(res, rendered);
572
+ void setResponse(res, rendered);
572
573
  });
573
574
  } else {
574
- setResponse(res, rendered);
575
+ void setResponse(res, rendered);
575
576
  }
576
577
  } catch (e) {
577
578
  const error = coalesce_to_error(e);
@@ -866,8 +866,12 @@ Tips:
866
866
  /** @type {import('vite').Manifest} */
867
867
  const client_manifest = JSON.parse(read(`${out}/client/${vite_config.build.manifest}`));
868
868
 
869
- const deps_of = /** @param {string} f */ (f) =>
870
- find_deps(client_manifest, posixify(path.relative('.', f)), false);
869
+ /**
870
+ * @param {string} entry
871
+ * @param {boolean} [add_dynamic_css]
872
+ */
873
+ const deps_of = (entry, add_dynamic_css = false) =>
874
+ find_deps(client_manifest, posixify(path.relative('.', entry)), add_dynamic_css);
871
875
 
872
876
  if (svelte_config.kit.output.bundleStrategy === 'split') {
873
877
  const start = deps_of(`${runtime_directory}/client/entry.js`);
@@ -888,14 +892,20 @@ Tips:
888
892
  // similar to that on the client, with as much information computed upfront so that we
889
893
  // don't need to include any code of the actual routes in the server bundle.
890
894
  if (svelte_config.kit.router.resolution === 'server') {
891
- build_data.client.nodes = manifest_data.nodes.map((node, i) => {
895
+ const nodes = manifest_data.nodes.map((node, i) => {
892
896
  if (node.component || node.universal) {
893
- return resolve_symlinks(
897
+ const entry = `${kit.outDir}/generated/client-optimized/nodes/${i}.js`;
898
+ const deps = deps_of(entry, true);
899
+ const file = resolve_symlinks(
894
900
  client_manifest,
895
901
  `${kit.outDir}/generated/client-optimized/nodes/${i}.js`
896
902
  ).chunk.file;
903
+
904
+ return { file, css: deps.stylesheets };
897
905
  }
898
906
  });
907
+ build_data.client.nodes = nodes.map((node) => node?.file);
908
+ build_data.client.css = nodes.map((node) => node?.css);
899
909
 
900
910
  build_data.client.routes = compact(
901
911
  manifest_data.routes.map((route) => {
@@ -192,7 +192,7 @@ export async function preview(vite, vite_config, svelte_config) {
192
192
  request: req
193
193
  });
194
194
 
195
- setResponse(
195
+ await setResponse(
196
196
  res,
197
197
  await server.respond(request, {
198
198
  getClientAddress: () => {
@@ -109,7 +109,7 @@ export function enhance(form_element, submit = () => {}) {
109
109
  result.type === 'redirect' ||
110
110
  result.type === 'error'
111
111
  ) {
112
- applyAction(result);
112
+ await applyAction(result);
113
113
  }
114
114
  };
115
115
 
@@ -205,7 +205,7 @@ export function enhance(form_element, submit = () => {}) {
205
205
  result = { type: 'error', error };
206
206
  }
207
207
 
208
- callback({
208
+ await callback({
209
209
  action,
210
210
  formData: form_data,
211
211
  formElement: form_element,
@@ -11,5 +11,5 @@ import * as app from '__sveltekit/manifest';
11
11
  * @param {import('./types.js').HydrateOptions} options
12
12
  */
13
13
  export function start(element, options) {
14
- kit.start(app, element, options);
14
+ void kit.start(app, element, options);
15
15
  }
@@ -19,7 +19,8 @@ import {
19
19
  origin,
20
20
  scroll_state,
21
21
  notifiable_store,
22
- create_updated_store
22
+ create_updated_store,
23
+ load_css
23
24
  } from './utils.js';
24
25
  import { base } from '__sveltekit/paths';
25
26
  import * as devalue from 'devalue';
@@ -39,7 +40,9 @@ import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../sh
39
40
  import { get_message, get_status } from '../../utils/error.js';
40
41
  import { writable } from 'svelte/store';
41
42
  import { page, update, navigating } from './state.svelte.js';
42
- import { add_data_suffix, add_resolution_prefix } from '../pathname.js';
43
+ import { add_data_suffix, add_resolution_suffix } from '../pathname.js';
44
+
45
+ export { load_css };
43
46
 
44
47
  const ICON_REL_ATTRIBUTES = new Set(['icon', 'shortcut icon', 'apple-touch-icon']);
45
48
 
@@ -273,8 +276,8 @@ export async function start(_app, _target, hydrate) {
273
276
  // connectivity errors after initialisation don't nuke the app
274
277
  default_layout_loader = _app.nodes[0];
275
278
  default_error_loader = _app.nodes[1];
276
- default_layout_loader();
277
- default_error_loader();
279
+ void default_layout_loader();
280
+ void default_error_loader();
278
281
 
279
282
  current_history_index = history.state?.[HISTORY_INDEX];
280
283
  current_navigation_index = history.state?.[NAVIGATION_INDEX];
@@ -306,7 +309,7 @@ export async function start(_app, _target, hydrate) {
306
309
  if (hydrate) {
307
310
  await _hydrate(target, hydrate);
308
311
  } else {
309
- goto(app.hash ? decode_hash(new URL(location.href)) : location.href, {
312
+ await goto(app.hash ? decode_hash(new URL(location.href)) : location.href, {
310
313
  replaceState: true
311
314
  });
312
315
  }
@@ -1265,7 +1268,7 @@ async function get_navigation_intent(url, invalidating) {
1265
1268
  /** @type {{ route?: import('types').CSRRouteServer, params: Record<string, string>}} */
1266
1269
  const { route, params } = await import(
1267
1270
  /* @vite-ignore */
1268
- add_resolution_prefix(url.pathname)
1271
+ add_resolution_suffix(url.pathname)
1269
1272
  );
1270
1273
 
1271
1274
  if (!route) return;
@@ -1448,7 +1451,7 @@ async function navigate({
1448
1451
  route: { id: null }
1449
1452
  });
1450
1453
  } else {
1451
- _goto(new URL(navigation_result.location, url).href, {}, redirect_count + 1, nav_token);
1454
+ await _goto(new URL(navigation_result.location, url).href, {}, redirect_count + 1, nav_token);
1452
1455
  return false;
1453
1456
  }
1454
1457
  } else if (/** @type {number} */ (navigation_result.props.page.status) >= 400) {
@@ -1644,14 +1647,14 @@ function setup_preload() {
1644
1647
 
1645
1648
  clearTimeout(mousemove_timeout);
1646
1649
  mousemove_timeout = setTimeout(() => {
1647
- preload(target, 2);
1650
+ void preload(target, 2);
1648
1651
  }, 20);
1649
1652
  });
1650
1653
 
1651
1654
  /** @param {Event} event */
1652
1655
  function tap(event) {
1653
1656
  if (event.defaultPrevented) return;
1654
- preload(/** @type {Element} */ (event.composedPath()[0]), 1);
1657
+ void preload(/** @type {Element} */ (event.composedPath()[0]), 1);
1655
1658
  }
1656
1659
 
1657
1660
  container.addEventListener('mousedown', tap);
@@ -1661,7 +1664,7 @@ function setup_preload() {
1661
1664
  (entries) => {
1662
1665
  for (const entry of entries) {
1663
1666
  if (entry.isIntersecting) {
1664
- _preload_code(new URL(/** @type {HTMLAnchorElement} */ (entry.target).href));
1667
+ void _preload_code(new URL(/** @type {HTMLAnchorElement} */ (entry.target).href));
1665
1668
  observer.unobserve(entry.target);
1666
1669
  }
1667
1670
  }
@@ -1677,8 +1680,6 @@ function setup_preload() {
1677
1680
  const a = find_anchor(element, container);
1678
1681
  if (!a || a === current_a) return;
1679
1682
 
1680
- current_a = a;
1681
-
1682
1683
  const { url, external, download } = get_link_info(a, base, app.hash);
1683
1684
  if (external || download) return;
1684
1685
 
@@ -1689,10 +1690,11 @@ function setup_preload() {
1689
1690
 
1690
1691
  if (!options.reload && !same_url) {
1691
1692
  if (priority <= options.preload_data) {
1693
+ current_a = a;
1692
1694
  const intent = await get_navigation_intent(url, false);
1693
1695
  if (intent) {
1694
1696
  if (DEV) {
1695
- _preload_data(intent).then((result) => {
1697
+ void _preload_data(intent).then((result) => {
1696
1698
  if (result.type === 'loaded' && result.state.error) {
1697
1699
  console.warn(
1698
1700
  `Preloading data for ${intent.url.pathname} failed with the following error: ${result.state.error.message}\n` +
@@ -1703,11 +1705,12 @@ function setup_preload() {
1703
1705
  }
1704
1706
  });
1705
1707
  } else {
1706
- _preload_data(intent);
1708
+ void _preload_data(intent);
1707
1709
  }
1708
1710
  }
1709
1711
  } else if (priority <= options.preload_code) {
1710
- _preload_code(/** @type {URL} */ (url));
1712
+ current_a = a;
1713
+ void _preload_code(/** @type {URL} */ (url));
1711
1714
  }
1712
1715
  }
1713
1716
  }
@@ -1727,7 +1730,7 @@ function setup_preload() {
1727
1730
  }
1728
1731
 
1729
1732
  if (options.preload_code === PRELOAD_PRIORITIES.eager) {
1730
- _preload_code(/** @type {URL} */ (url));
1733
+ void _preload_code(/** @type {URL} */ (url));
1731
1734
  }
1732
1735
  }
1733
1736
  }
@@ -2127,10 +2130,10 @@ export async function applyAction(result) {
2127
2130
  root.$set(navigation_result.props);
2128
2131
  update(navigation_result.props.page);
2129
2132
 
2130
- tick().then(reset_focus);
2133
+ void tick().then(reset_focus);
2131
2134
  }
2132
2135
  } else if (result.type === 'redirect') {
2133
- _goto(result.location, { invalidateAll: true }, 0);
2136
+ await _goto(result.location, { invalidateAll: true }, 0);
2134
2137
  } else {
2135
2138
  page.form = result.data;
2136
2139
  page.status = result.status;
@@ -2311,7 +2314,7 @@ function _start_router() {
2311
2314
  setTimeout(fulfil, 100); // fallback for edge case where rAF doesn't fire because e.g. tab was backgrounded
2312
2315
  });
2313
2316
 
2314
- navigate({
2317
+ await navigate({
2315
2318
  type: 'link',
2316
2319
  url,
2317
2320
  keepfocus: options.keepfocus,
@@ -2362,7 +2365,7 @@ function _start_router() {
2362
2365
  // @ts-expect-error `URLSearchParams(fd)` is kosher, but typescript doesn't know that
2363
2366
  url.search = new URLSearchParams(data).toString();
2364
2367
 
2365
- navigate({
2368
+ void navigate({
2366
2369
  type: 'form',
2367
2370
  url,
2368
2371
  keepfocus: options.keepfocus,
@@ -2455,7 +2458,7 @@ function _start_router() {
2455
2458
  // (surprisingly!) mutates `current.url`, allowing us to
2456
2459
  // detect it and trigger a navigation
2457
2460
  if (current.url.hash === location.hash) {
2458
- navigate({ type: 'goto', url: decode_hash(current.url) });
2461
+ void navigate({ type: 'goto', url: decode_hash(current.url) });
2459
2462
  }
2460
2463
  }
2461
2464
  });
@@ -1,3 +1,3 @@
1
1
  // we expose this as a separate entry point (rather than treating client.js as the entry point)
2
- // so that everything other than `start` can be treeshaken
3
- export { start } from './client.js';
2
+ // so that everything other than `start`/`load_css` can be treeshaken
3
+ export { start, load_css } from './client.js';
@@ -25,7 +25,7 @@ if (DEV && BROWSER) {
25
25
  can_inspect_stack_trace = stack.includes('check_stack_trace');
26
26
  };
27
27
 
28
- check_stack_trace();
28
+ void check_stack_trace();
29
29
 
30
30
  /**
31
31
  * @param {RequestInfo | URL} input
@@ -331,3 +331,40 @@ export function is_external_url(url, base, hash_routing) {
331
331
 
332
332
  return false;
333
333
  }
334
+
335
+ /** @type {Record<string, boolean>} */
336
+ const seen = {};
337
+
338
+ /**
339
+ * Used for server-side resolution, to replicate Vite's CSS loading behaviour in production.
340
+ *
341
+ * Closely modelled after https://github.com/vitejs/vite/blob/3dd12f4724130fdf8ba44c6d3252ebdff407fd47/packages/vite/src/node/plugins/importAnalysisBuild.ts#L214
342
+ * (which ideally we could just use directly, but it's not exported)
343
+ * @param {string[]} deps
344
+ */
345
+ export function load_css(deps) {
346
+ if (__SVELTEKIT_CLIENT_ROUTING__) return;
347
+
348
+ const csp_nonce_meta = /** @type {HTMLMetaElement} */ (
349
+ document.querySelector('meta[property=csp-nonce]')
350
+ );
351
+ const csp_nonce = csp_nonce_meta?.nonce || csp_nonce_meta?.getAttribute('nonce');
352
+
353
+ for (const dep of deps) {
354
+ if (dep in seen) continue;
355
+ seen[dep] = true;
356
+
357
+ if (document.querySelector(`link[href="${dep}"][rel="stylesheet"]`)) {
358
+ continue;
359
+ }
360
+
361
+ const link = document.createElement('link');
362
+ link.rel = 'stylesheet';
363
+ link.crossOrigin = '';
364
+ link.href = dep;
365
+ if (csp_nonce) {
366
+ link.setAttribute('nonce', csp_nonce);
367
+ }
368
+ document.head.appendChild(link);
369
+ }
370
+ }
@@ -1,5 +1,3 @@
1
- import { base, app_dir } from '__sveltekit/paths';
2
-
3
1
  const DATA_SUFFIX = '/__data.json';
4
2
  const HTML_DATA_SUFFIX = '.html__data.json';
5
3
 
@@ -23,14 +21,14 @@ export function strip_data_suffix(pathname) {
23
21
  return pathname.slice(0, -DATA_SUFFIX.length);
24
22
  }
25
23
 
26
- const ROUTE_PREFIX = `${base}/${app_dir}/route`;
24
+ const ROUTE_SUFFIX = '/__route.js';
27
25
 
28
26
  /**
29
27
  * @param {string} pathname
30
28
  * @returns {boolean}
31
29
  */
32
- export function has_resolution_prefix(pathname) {
33
- return pathname === `${ROUTE_PREFIX}.js` || pathname.startsWith(`${ROUTE_PREFIX}/`);
30
+ export function has_resolution_suffix(pathname) {
31
+ return pathname.endsWith(ROUTE_SUFFIX);
34
32
  }
35
33
 
36
34
  /**
@@ -38,17 +36,14 @@ export function has_resolution_prefix(pathname) {
38
36
  * @param {string} pathname
39
37
  * @returns {string}
40
38
  */
41
- export function add_resolution_prefix(pathname) {
42
- let normalized = pathname.slice(base.length);
43
- if (normalized.endsWith('/')) normalized = normalized.slice(0, -1);
44
-
45
- return `${ROUTE_PREFIX}${normalized}.js`;
39
+ export function add_resolution_suffix(pathname) {
40
+ return pathname.replace(/\/$/, '') + ROUTE_SUFFIX;
46
41
  }
47
42
 
48
43
  /**
49
44
  * @param {string} pathname
50
45
  * @returns {string}
51
46
  */
52
- export function strip_resolution_prefix(pathname) {
53
- return base + (pathname.slice(ROUTE_PREFIX.length, -3) || '/');
47
+ export function strip_resolution_suffix(pathname) {
48
+ return pathname.slice(0, -ROUTE_SUFFIX.length);
54
49
  }
@@ -242,7 +242,7 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
242
242
  dependency = { response, body: null };
243
243
  state.prerendering.dependencies.set(url.pathname, dependency);
244
244
  }
245
- } else {
245
+ } else if (url.protocol === 'https:' || url.protocol === 'http:') {
246
246
  // simulate CORS errors and "no access to body in no-cors mode" server-side for consistency with client-side behaviour
247
247
  const mode = input instanceof Request ? input.mode : (init?.mode ?? 'cors');
248
248
  if (mode === 'no-cors') {
@@ -14,7 +14,7 @@ import { create_async_iterator } from '../../../utils/streaming.js';
14
14
  import { SVELTE_KIT_ASSETS } from '../../../constants.js';
15
15
  import { SCHEME } from '../../../utils/url.js';
16
16
  import { create_server_routing_response, generate_route_object } from './server_routing.js';
17
- import { add_resolution_prefix } from '../../pathname.js';
17
+ import { add_resolution_suffix } from '../../pathname.js';
18
18
 
19
19
  // TODO rename this function/module
20
20
 
@@ -321,9 +321,9 @@ export async function render_response({
321
321
  }
322
322
  }
323
323
 
324
- // prerender a `/_app/route/path/to/page.js` module
324
+ // prerender a `/path/to/page/__route.js` module
325
325
  if (manifest._.client.routes && state.prerendering && !state.prerendering.fallback) {
326
- const pathname = add_resolution_prefix(event.url.pathname);
326
+ const pathname = add_resolution_suffix(event.url.pathname);
327
327
 
328
328
  state.prerendering.dependencies.set(
329
329
  pathname,
@@ -105,10 +105,39 @@ export function create_server_routing_response(route, params, url, manifest) {
105
105
 
106
106
  if (route) {
107
107
  const csr_route = generate_route_object(route, url, manifest);
108
- const body = `export const route = ${csr_route}; export const params = ${JSON.stringify(params)};`;
108
+ const body = `${create_css_import(route, url, manifest)}\nexport const route = ${csr_route}; export const params = ${JSON.stringify(params)};`;
109
109
 
110
110
  return { response: text(body, { headers }), body };
111
111
  } else {
112
112
  return { response: text('', { headers }), body: '' };
113
113
  }
114
114
  }
115
+
116
+ /**
117
+ * This function generates the client-side import for the CSS files that are
118
+ * associated with the current route. Vite takes care of that when using
119
+ * client-side route resolution, but for server-side resolution it does
120
+ * not know about the CSS files automatically.
121
+ *
122
+ * @param {import('types').SSRClientRoute} route
123
+ * @param {URL} url
124
+ * @param {import('@sveltejs/kit').SSRManifest} manifest
125
+ * @returns {string}
126
+ */
127
+ function create_css_import(route, url, manifest) {
128
+ const { errors, layouts, leaf } = route;
129
+
130
+ let css = '';
131
+
132
+ for (const node of [...errors, ...layouts.map((l) => l?.[1]), leaf[1]]) {
133
+ if (typeof node !== 'number') continue;
134
+ const node_css = manifest._.client.css?.[node];
135
+ for (const css_path of node_css ?? []) {
136
+ css += `'${assets || base}/${css_path}',`;
137
+ }
138
+ }
139
+
140
+ if (!css) return '';
141
+
142
+ return `${create_client_import(/** @type {string} */ (manifest._.client.start), url)}.then(x => x.load_css([${css}]));`;
143
+ }
@@ -30,9 +30,9 @@ import { resolve_route } from './page/server_routing.js';
30
30
  import { validateHeaders } from './validate-headers.js';
31
31
  import {
32
32
  has_data_suffix,
33
- has_resolution_prefix,
33
+ has_resolution_suffix,
34
34
  strip_data_suffix,
35
- strip_resolution_prefix
35
+ strip_resolution_suffix
36
36
  } from '../pathname.js';
37
37
 
38
38
  /* global __SVELTEKIT_ADAPTER_NAME__ */
@@ -94,11 +94,11 @@ export async function respond(request, options, manifest, state) {
94
94
  * If the request is for a route resolution, first modify the URL, then continue as normal
95
95
  * for path resolution, then return the route object as a JS file.
96
96
  */
97
- const is_route_resolution_request = has_resolution_prefix(url.pathname);
97
+ const is_route_resolution_request = has_resolution_suffix(url.pathname);
98
98
  const is_data_request = has_data_suffix(url.pathname);
99
99
 
100
100
  if (is_route_resolution_request) {
101
- url.pathname = strip_resolution_prefix(url.pathname);
101
+ url.pathname = strip_resolution_suffix(url.pathname);
102
102
  } else if (is_data_request) {
103
103
  url.pathname =
104
104
  strip_data_suffix(url.pathname) +
@@ -80,6 +80,12 @@ export interface BuildData {
80
80
  * Only set in case of `router.resolution === 'server'`.
81
81
  */
82
82
  nodes?: (string | undefined)[];
83
+ /**
84
+ * CSS files referenced in the entry points of the layouts/pages.
85
+ * An entry is undefined if the layout/page has no component or universal file (i.e. only has a `.server.js` file) or if has no CSS.
86
+ * Only set in case of `router.resolution === 'server'`.
87
+ */
88
+ css?: (string[] | undefined)[];
83
89
  /**
84
90
  * Contains the client route manifest in a form suitable for the server which is used for server side route resolution.
85
91
  * Notably, it contains all routes, regardless of whether they are prerendered or not (those are missing in the optimized server route manifest).
@@ -121,7 +127,7 @@ export type CSRRoute = {
121
127
  };
122
128
 
123
129
  /**
124
- * Definition of a client side route as transported via `_app/route/...` when using server-side route resolution.
130
+ * Definition of a client side route as transported via `<pathname>/__route.js` when using server-side route resolution.
125
131
  */
126
132
  export type CSRRouteServer = {
127
133
  id: string;
package/src/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // generated during release, do not modify
2
2
 
3
3
  /** @type {string} */
4
- export const VERSION = '2.17.1';
4
+ export const VERSION = '2.17.3';
package/types/index.d.ts CHANGED
@@ -1466,7 +1466,7 @@ declare module '@sveltejs/kit' {
1466
1466
  * @param invalidateAll Set `invalidateAll: false` if you don't want the action to call `invalidateAll` after submission.
1467
1467
  */
1468
1468
  update: (options?: { reset?: boolean; invalidateAll?: boolean }) => Promise<void>;
1469
- }) => void)
1469
+ }) => MaybePromise<void>)
1470
1470
  >;
1471
1471
 
1472
1472
  /**
@@ -1727,6 +1727,12 @@ declare module '@sveltejs/kit' {
1727
1727
  * Only set in case of `router.resolution === 'server'`.
1728
1728
  */
1729
1729
  nodes?: (string | undefined)[];
1730
+ /**
1731
+ * CSS files referenced in the entry points of the layouts/pages.
1732
+ * An entry is undefined if the layout/page has no component or universal file (i.e. only has a `.server.js` file) or if has no CSS.
1733
+ * Only set in case of `router.resolution === 'server'`.
1734
+ */
1735
+ css?: (string[] | undefined)[];
1730
1736
  /**
1731
1737
  * Contains the client route manifest in a form suitable for the server which is used for server side route resolution.
1732
1738
  * Notably, it contains all routes, regardless of whether they are prerendered or not (those are missing in the optimized server route manifest).
@@ -160,6 +160,6 @@
160
160
  null,
161
161
  null
162
162
  ],
163
- "mappings": "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",
163
+ "mappings": "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",
164
164
  "ignoreList": []
165
165
  }