Repository: sveltejs/kit (js)

Issue:
`cookies.get` incorrectly logs a warning when a cookie was removed from the browser instead of `cookies.delete`
### Describe the bug

Context provided by @dummdidumm in Discord:
> Some context about this warning and how the logic is to surface it:
Why this warning: Cookies have a path. This means they are only available at this path and below. So a path of /foo means your cookie is available at /foo, /foo/bar etc, but not / or /sthelse. Not setting the path value means the cookie's path is set to where the cookie is set on. This is a source of confusion ("why is my cookie not deleted/set/available?") so we added that warning. That said, that warning could probably use some love, at least a link to some more in-depth explanation what this is about.
> 
> Logic to surface it: Whenever you call cookies.set in dev mode, that cookie's name and its path are stored in a map, and whenever you call cookies.get and it turns up nothing, it prints a warning if a cookie with that name exists in that map. False positives could occur if you remove a cookie through another method - and writing this I just realized that session cookies are probably also false positives: If you set a cookie, close the browser tab and open it again, a session cookie is removed from the browser, but not from the map. Maybe that's something that happens here?

It seems that these proposed false positives are correct, when a cookie is removed via exterior means but still expected to be there via `cookies.get` this warning is thrown. However, the warning says "`did you mean to set its 'path' to '/'?`" even when the path is set correctly. 

I propose that this warning is only logged when the path isn't `/`, and print the path(s) associated with the cookie. If it is already set to `/`, then these cookies should be removed from the map to align with the lack of them in the browser. I'll attempt to submit a PR to fix this myself shortly, but I'm not super familiar with the inner workings of the project, so it might not be perfect.

### Reproduction

A simple reproduction can be found in [CookiesGetWarningRepro](https://github.com/ptlthg/CookiesGetWarningRepro), but it's a simple thing to check. Just remove a cookie from your browser in dev tools, then refresh or try to access it via `cookies.get` afterwards. The warning should then be logged.

### Logs

```Shell
Cookie with name 'session-cookie' was not found, but a cookie with that name exists at a sub path. Did you mean to set its 'path' to '/'?
Cookie with name 'normal-cookie' was not found, but a cookie with that name exists at a sub path. Did you mean to set its 'path' to '/'? 
Cookie with name 'expires-cookie' was not found, but a cookie with that name exists at a sub path. Did you mean to set its 'path' to '/'?
```


### System Info

```Shell
System:
    OS: Windows 10 10.0.19044
    CPU: (16) x64 AMD Ryzen 7 5800H with Radeon Graphics
    Memory: 45.67 GB / 59.86 GB
  Binaries:
    Node: 18.8.0 - C:\Program Files\nodejs\node.EXE
    npm: 8.18.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (107.0.1418.35)
    Internet Explorer: 11.0.19041.1566
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.87
    @sveltejs/kit: next => 1.0.0-next.535
    svelte: ^3.44.0 => 3.52.0
    vite: ^3.1.0 => 3.2.2
```


### Severity

annoyance

### Additional Information

_No response_

Pull request description:
[fix] better cookie warning checks
Fixes #7510

### Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
- [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it solves.
- [x] Ideally, include a test that fails without this PR but passes with it.

### Tests
- [x] Run the tests with `pnpm test` and lint the project with `pnpm lint` and `pnpm check`

### Changesets
- [x] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running `pnpm changeset` and following the prompts. All changesets should be `patch` until SvelteKit 1.0


Patch:
diff --git a/.changeset/many-timers-accept.md b/.changeset/many-timers-accept.md
new file mode 100644
index 000000000..76efaa329
--- /dev/null
+++ b/.changeset/many-timers-accept.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[feat] better navigation interfaces
diff --git a/.changeset/pre.json b/.changeset/pre.json
index 03fa179b4..f08d9a5ac 100644
--- a/.changeset/pre.json
+++ b/.changeset/pre.json
@@ -671,6 +671,7 @@
     "many-planes-taste",
     "many-pugs-work",
     "many-suns-push",
+    "many-timers-accept",
     "mean-bananas-live",
     "mean-chefs-swim",
     "mean-crews-unite",
@@ -1254,6 +1255,7 @@
     "ten-apricots-admire",
     "ten-berries-develop",
     "ten-gorillas-itch",
+    "ten-hairs-drum",
     "ten-hairs-perform",
     "ten-mice-kneel",
     "ten-pets-tease",
diff --git a/.changeset/ten-hairs-drum.md b/.changeset/ten-hairs-drum.md
new file mode 100644
index 000000000..79f452719
--- /dev/null
+++ b/.changeset/ten-hairs-drum.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+custom aliases resolved in service worker builds
diff --git a/.changeset/violet-candles-compare.md b/.changeset/violet-candles-compare.md
new file mode 100644
index 000000000..c71675cf0
--- /dev/null
+++ b/.changeset/violet-candles-compare.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[fix] better cookie warning checks
diff --git a/documentation/docs/20-core-concepts/40-page-options.md b/documentation/docs/20-core-concepts/40-page-options.md
index 6da5921c7..9ad9153d1 100644
--- a/documentation/docs/20-core-concepts/40-page-options.md
+++ b/documentation/docs/20-core-concepts/40-page-options.md
@@ -83,7 +83,7 @@ Since these routes cannot be dynamically server-rendered, this will cause errors
 
 ### ssr
 
-Normally, SvelteKit renders your page on the server first and sends that HTML to the client where it's hydrated. If you set `ssr` to `false`, it renders an empty 'shell' page instead. This is useful if your page is unable to be rendered on the server (because you use browser-only globals like `document` for example), but in most situations it's not recommended ([see appendix](/docs/glossary#ssr)). If you put this into your root `+layout.js`, you create an SPA (all pages are client-side rendered only).
+Normally, SvelteKit renders your page on the server first and sends that HTML to the client where it's hydrated. If you set `ssr` to `false`, it renders an empty 'shell' page instead. This is useful if your page is unable to be rendered on the server (because you use browser-only globals like `document` for example), but in most situations it's not recommended ([see appendix](/docs/glossary#ssr)).
 
 ```js
 /// file: +page.js
diff --git a/documentation/docs/60-appendix/10-migrating.md b/documentation/docs/60-appendix/10-migrating.md
index 18cef9023..4827b530c 100644
--- a/documentation/docs/60-appendix/10-migrating.md
+++ b/documentation/docs/60-appendix/10-migrating.md
@@ -172,7 +172,7 @@ const minification_options = {
 	minifyCSS: true,
 	minifyJS: false,
 	removeAttributeQuotes: true,
-	removeComments: true,
+	removeComments: false, // some hydration code needs comments, so leave them in
 	removeOptionalTags: true,
 	removeRedundantAttributes: true,
 	removeScriptTypeAttributes: true,
diff --git a/packages/kit/CHANGELOG.md b/packages/kit/CHANGELOG.md
index 9422035c1..807510270 100644
--- a/packages/kit/CHANGELOG.md
+++ b/packages/kit/CHANGELOG.md
@@ -1,5 +1,17 @@
 # @sveltejs/kit
 
+## 1.0.0-next.537
+
+### Patch Changes
+
+- [feat] better navigation interfaces ([#7529](https://github.com/sveltejs/kit/pull/7529))
+
+## 1.0.0-next.536
+
+### Patch Changes
+
+- custom aliases resolved in service worker builds ([#7500](https://github.com/sveltejs/kit/pull/7500))
+
 ## 1.0.0-next.535
 
 ### Patch Changes
diff --git a/packages/kit/package.json b/packages/kit/package.json
index a1617e9cb..0a7547329 100644
--- a/packages/kit/package.json
+++ b/packages/kit/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@sveltejs/kit",
-	"version": "1.0.0-next.535",
+	"version": "1.0.0-next.537",
 	"repository": {
 		"type": "git",
 		"url": "https://github.com/sveltejs/kit",
diff --git a/packages/kit/src/exports/vite/build/build_service_worker.js b/packages/kit/src/exports/vite/build/build_service_worker.js
index 01649aee7..1bfecfbfb 100644
--- a/packages/kit/src/exports/vite/build/build_service_worker.js
+++ b/packages/kit/src/exports/vite/build/build_service_worker.js
@@ -1,6 +1,7 @@
 import fs from 'fs';
 import * as vite from 'vite';
 import { s } from '../../../utils/misc.js';
+import { get_config_aliases } from '../utils.js';
 import { assets_base } from './utils.js';
 
 /**
@@ -82,10 +83,10 @@ export async function build_service_worker(
 		define: vite_config.define,
 		configFile: false,
 		resolve: {
-			alias: {
-				'$service-worker': service_worker,
-				$lib: config.kit.files.lib
-			}
+			alias: [
+				...get_config_aliases(config.kit),
+				{ find: '$service-worker', replacement: service_worker }
+			]
 		}
 	});
 }
diff --git a/packages/kit/src/exports/vite/build/utils.js b/packages/kit/src/exports/vite/build/utils.js
index e7e1ea77b..9f51ee9a8 100644
--- a/packages/kit/src/exports/vite/build/utils.js
+++ b/packages/kit/src/exports/vite/build/utils.js
@@ -1,7 +1,7 @@
 import fs from 'fs';
 import path from 'path';
 import * as vite from 'vite';
-import { get_aliases } from '../utils.js';
+import { get_config_aliases, get_app_aliases } from '../utils.js';
 
 /**
  * @typedef {import('rollup').RollupOutput} RollupOutput
@@ -143,7 +143,7 @@ export function get_default_build_config({ config, input, ssr, outDir }) {
 		},
 		publicDir: ssr ? false : config.kit.files.assets,
 		resolve: {
-			alias: get_aliases(config.kit)
+			alias: [...get_app_aliases(config.kit), ...get_config_aliases(config.kit)]
 		},
 		optimizeDeps: {
 			exclude: ['@sveltejs/kit']
diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js
index 941a87568..e3d88ce8c 100644
--- a/packages/kit/src/exports/vite/index.js
+++ b/packages/kit/src/exports/vite/index.js
@@ -14,7 +14,7 @@ import { generate_manifest } from '../../core/generate_manifest/index.js';
 import { runtime_directory, logger } from '../../core/utils.js';
 import { find_deps, get_default_build_config } from './build/utils.js';
 import { preview } from './preview/index.js';
-import { get_aliases, get_env } from './utils.js';
+import { get_config_aliases, get_app_aliases, get_env } from './utils.js';
 import { prevent_illegal_rollup_imports } from './graph_analysis/index.js';
 import { fileURLToPath } from 'node:url';
 import { create_static_module, create_dynamic_module } from '../../core/env.js';
@@ -257,7 +257,7 @@ function kit() {
 				},
 				publicDir: svelte_config.kit.files.assets,
 				resolve: {
-					alias: get_aliases(svelte_config.kit)
+					alias: [...get_app_aliases(svelte_config.kit), ...get_config_aliases(svelte_config.kit)]
 				},
 				root: cwd,
 				server: {
diff --git a/packages/kit/src/exports/vite/utils.js b/packages/kit/src/exports/vite/utils.js
index cfbafa7b6..9f729187b 100644
--- a/packages/kit/src/exports/vite/utils.js
+++ b/packages/kit/src/exports/vite/utils.js
@@ -96,15 +96,14 @@ function merge_into(a, b) {
 
 /**
  * Transforms kit.alias to a valid vite.resolve.alias array.
+ *
  * Related to tsconfig path alias creation.
  *
  * @param {import('types').ValidatedKitConfig} config
  * */
-export function get_aliases(config) {
+export function get_config_aliases(config) {
 	/** @type {import('vite').Alias[]} */
 	const alias = [
-		{ find: '__GENERATED__', replacement: path.posix.join(config.outDir, 'generated') },
-		{ find: '$app', replacement: `${runtime_directory}/app` },
 		// For now, we handle `$lib` specially here rather than make it a default value for
 		// `config.kit.alias` since it has special meaning for packaging, etc.
 		{ find: '$lib', replacement: config.files.lib }
@@ -135,6 +134,21 @@ export function get_aliases(config) {
 	return alias;
 }
 
+/**
+ * Returns Vite aliases for generated and runtime files.
+ *
+ * @param {import('types').ValidatedKitConfig} config
+ * */
+export function get_app_aliases(config) {
+	/** @type {import('vite').Alias[]} */
+	const alias = [
+		{ find: '__GENERATED__', replacement: path.posix.join(config.outDir, 'generated') },
+		{ find: '$app', replacement: `${runtime_directory}/app` }
+	];
+
+	return alias;
+}
+
 /**
  * @param {string} str
  */
diff --git a/packages/kit/src/exports/vite/utils.spec.js b/packages/kit/src/exports/vite/utils.spec.js
index f2160386d..554f7b883 100644
--- a/packages/kit/src/exports/vite/utils.spec.js
+++ b/packages/kit/src/exports/vite/utils.spec.js
@@ -3,7 +3,7 @@ import { test } from 'uvu';
 import * as assert from 'uvu/assert';
 import { validate_config } from '../../core/config/index.js';
 import { posixify } from '../../utils/filesystem.js';
-import { deep_merge, get_aliases, merge_vite_configs } from './utils.js';
+import { deep_merge, get_app_aliases, get_config_aliases, merge_vite_configs } from './utils.js';
 
 test('basic test no conflicts', async () => {
 	const merged = deep_merge(
@@ -211,7 +211,10 @@ test('transform kit.alias to resolve.alias', () => {
 		}
 	});
 
-	const transformed = get_aliases(config.kit).map((entry) => {
+	// combine aliases from config with generated and runtime aliases
+	const aliases = [...get_app_aliases(config.kit), ...get_config_aliases(config.kit)];
+
+	const transformed = aliases.map((entry) => {
 		const replacement = posixify(path.relative('.', entry.replacement));
 
 		return {
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index b622af0c4..96d65b89a 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -83,10 +83,10 @@ export function create_client({ target, base, trailing_slash }) {
 	let load_cache = null;
 
 	const callbacks = {
-		/** @type {Array<(navigation: import('types').Navigation & { cancel: () => void }) => void>} */
+		/** @type {Array<(navigation: import('types').BeforeNavigate) => void>} */
 		before_navigate: [],
 
-		/** @type {Array<(navigation: import('types').Navigation) => void>} */
+		/** @type {Array<(navigation: import('types').AfterNavigate) => void>} */
 		after_navigate: []
 	};
 
@@ -382,7 +382,7 @@ export function create_client({ target, base, trailing_slash }) {
 		});
 		post_update();
 
-		/** @type {import('types').Navigation} */
+		/** @type {import('types').AfterNavigate} */
 		const navigation = {
 			from: null,
 			to: add_url_properties('to', {
@@ -1116,7 +1116,9 @@ export function create_client({ target, base, trailing_slash }) {
 			nav_token,
 			() => {
 				navigating = false;
-				callbacks.after_navigate.forEach((fn) => fn(navigation));
+				callbacks.after_navigate.forEach((fn) =>
+					fn(/** @type {import('types').AfterNavigate} */ (navigation))
+				);
 				stores.navigating.set(null);
 			}
 		);
@@ -1307,7 +1309,7 @@ export function create_client({ target, base, trailing_slash }) {
 				if (!navigating) {
 					// If we're navigating, beforeNavigate was already called. If we end up in here during navigation,
 					// it's due to an external or full-page-reload link, for which we don't want to call the hook again.
-					/** @type {import('types').Navigation & { cancel: () => void }} */
+					/** @type {import('types').BeforeNavigate} */
 					const navigation = {
 						from: add_url_properties('from', {
 							params: current.params,
diff --git a/packages/kit/src/runtime/server/cookie.js b/packages/kit/src/runtime/server/cookie.js
index a6a4a2f9f..75672fe57 100644
--- a/packages/kit/src/runtime/server/cookie.js
+++ b/packages/kit/src/runtime/server/cookie.js
@@ -15,9 +15,35 @@ const cookie_paths = {};
  */
 export function get_cookies(request, url, options) {
 	const header = request.headers.get('cookie') ?? '';
-
 	const initial_cookies = parse(header);
 
+	const normalized_url = normalize_path(
+		// Remove suffix: 'foo/__data.json' would mean the cookie path is '/foo',
+		// whereas a direct hit of /foo would mean the cookie path is '/'
+		has_data_suffix(url.pathname) ? strip_data_suffix(url.pathname) : url.pathname,
+		options.trailing_slash
+	);
+	// Emulate browser-behavior: if the cookie is set at '/foo/bar', its path is '/foo'
+	const default_path = normalized_url.split('/').slice(0, -1).join('/') || '/';
+
+	if (options.dev) {
+		// Remove all cookies that no longer exist according to the request
+		for (const name of Object.keys(cookie_paths)) {
+			cookie_paths[name] = new Set(
+				[...cookie_paths[name]].filter(
+					(path) => !path_matches(normalized_url, path) || name in initial_cookies
+				)
+			);
+		}
+		// Add all new cookies we might not have seen before
+		for (const name in initial_cookies) {
+			cookie_paths[name] = cookie_paths[name] ?? new Set();
+			if (![...cookie_paths[name]].some((path) => path_matches(normalized_url, path))) {
+				cookie_paths[name].add(default_path);
+			}
+		}
+	}
+
 	/** @type {Record<string, import('./page/types').Cookie>} */
 	const new_cookies = {};
 
@@ -57,9 +83,14 @@ export function get_cookies(request, url, options) {
 				return cookie;
 			}
 
-			if (c || cookie_paths[name]?.size > 0) {
+			const paths = new Set([...(cookie_paths[name] ?? [])]);
+			if (c) {
+				paths.add(c.options.path ?? default_path);
+			}
+			if (paths.size > 0) {
 				console.warn(
-					`Cookie with name '${name}' was not found, but a cookie with that name exists at a sub path. Did you mean to set its 'path' to '/'?`
+					// prettier-ignore
+					`Cookie with name '${name}' was not found at path '${url.pathname}', but a cookie with that name exists at these paths: '${[...paths].join("', '")}'. Did you mean to set its 'path' to '/' instead?`
 				);
 			}
 		},
@@ -70,17 +101,7 @@ export function get_cookies(request, url, options) {
 		 * @param {import('cookie').CookieSerializeOptions} opts
 		 */
 		set(name, value, opts = {}) {
-			let path = opts.path;
-			if (!path) {
-				const normalized = normalize_path(
-					// Remove suffix: 'foo/__data.json' would mean the cookie path is '/foo',
-					// whereas a direct hit of /foo would mean the cookie path is '/'
-					has_data_suffix(url.pathname) ? strip_data_suffix(url.pathname) : url.pathname,
-					options.trailing_slash
-				);
-				// Emulate browser-behavior: if the cookie is set at '/foo/bar', its path is '/foo'
-				path = normalized.split('/').slice(0, -1).join('/') || '/';
-			}
+			let path = opts.path ?? default_path;
 
 			new_cookies[name] = {
 				name,
@@ -93,11 +114,12 @@ export function get_cookies(request, url, options) {
 			};
 
 			if (options.dev) {
-				cookie_paths[name] = cookie_paths[name] || new Set();
+				cookie_paths[name] = cookie_paths[name] ?? new Set();
 				if (!value) {
 					if (!cookie_paths[name].has(path) && cookie_paths[name].size > 0) {
+						const paths = `'${Array.from(cookie_paths[name]).join("', '")}'`;
 						console.warn(
-							`Trying to delete cookie '${name}' at path '${path}', but a cookie with that name only exists at a different path.`
+							`Trying to delete cookie '${name}' at path '${path}', but a cookie with that name only exists at these paths: ${paths}.`
 						);
 					}
 					cookie_paths[name].delete(path);
diff --git a/packages/kit/types/ambient.d.ts b/packages/kit/types/ambient.d.ts
index bc96b872e..2f214d7d1 100644
--- a/packages/kit/types/ambient.d.ts
+++ b/packages/kit/types/ambient.d.ts
@@ -171,7 +171,7 @@ declare module '$app/forms' {
  * ```
  */
 declare module '$app/navigation' {
-	import { Navigation } from '@sveltejs/kit';
+	import { BeforeNavigate, AfterNavigate } from '@sveltejs/kit';
 
 	/**
 	 * If called when the page is being updated following a navigation (in `onMount` or `afterNavigate` or an action, for example), this disables SvelteKit's built-in scroll handling.
@@ -261,16 +261,14 @@ declare module '$app/navigation' {
 	 *
 	 * `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted.
 	 */
-	export function beforeNavigate(
-		callback: (navigation: Navigation & { cancel(): void }) => void
-	): void;
+	export function beforeNavigate(callback: (navigation: BeforeNavigate) => void): void;
 
 	/**
 	 * A lifecycle function that runs the supplied `callback` when the current component mounts, and also whenever we navigate to a new URL.
 	 *
 	 * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted.
 	 */
-	export function afterNavigate(callback: (navigation: Navigation) => void): void;
+	export function afterNavigate(callback: (navigation: AfterNavigate) => void): void;
 }
 
 /**
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index a690057eb..b6fa43320 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -414,13 +414,12 @@ export interface Navigation {
 	to: NavigationTarget | null;
 	/**
 	 * The type of navigation:
-	 * - `enter`: The app has hydrated
 	 * - `leave`: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document
 	 * - `link`: Navigation was triggered by a link click
 	 * - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
 	 * - `popstate`: Navigation was triggered by back/forward navigation
 	 */
-	type: NavigationType;
+	type: Omit<NavigationType, 'enter'>;
 	/**
 	 * Whether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation)
 	 */
@@ -431,6 +430,31 @@ export interface Navigation {
 	delta?: number;
 }
 
+/**
+ * The interface that corresponds to the `beforeNavigate`'s input parameter.
+ */
+export interface BeforeNavigate extends Navigation {
+	/**
+	 * Call this to prevent the navigation from starting.
+	 */
+	cancel(): void;
+}
+
+/**
+ * The interface that corresponds to the `afterNavigate`'s input parameter.
+ */
+export interface AfterNavigate extends Navigation {
+	/**
+	 * The type of navigation:
+	 * - `enter`: The app has hydrated
+	 * - `link`: Navigation was triggered by a link click
+	 * - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
+	 * - `popstate`: Navigation was triggered by back/forward navigation
+	 */
+	type: Omit<NavigationType, 'leave'>;
+	willUnload: false;
+}
+
 /**
  * The shape of the `$page` store
  */


Test patch:
diff --git a/packages/kit/test/apps/basics/src/app.d.ts b/packages/kit/test/apps/basics/src/app.d.ts
index 36f8f2739..15ac25fc1 100644
--- a/packages/kit/test/apps/basics/src/app.d.ts
+++ b/packages/kit/test/apps/basics/src/app.d.ts
@@ -1,7 +1,7 @@
 declare namespace App {
 	interface Locals {
 		answer: number;
-		name: string;
+		name?: string;
 		key: string;
 		params: Record<string, string>;
 	}
diff --git a/packages/kit/test/apps/basics/src/hooks.server.js b/packages/kit/test/apps/basics/src/hooks.server.js
index d210e114e..564ff59d5 100644
--- a/packages/kit/test/apps/basics/src/hooks.server.js
+++ b/packages/kit/test/apps/basics/src/hooks.server.js
@@ -44,7 +44,10 @@ export const handle = sequence(
 		return resolve(event);
 	},
 	({ event, resolve }) => {
-		event.locals.name = /** @type {string} */ (event.cookies.get('name'));
+		if (event.url.pathname.includes('fetch-credentialed')) {
+			// Only get the cookie at the test where we know it's set to avoid polluting our logs with (correct) warnings
+			event.locals.name = /** @type {string} */ (event.cookies.get('name'));
+		}
 		return resolve(event);
 	},
 	async ({ event, resolve }) => {
diff --git a/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.server.js b/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.server.js
index f39937f60..171f89ddd 100644
--- a/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.server.js
+++ b/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.server.js
@@ -1,6 +1,6 @@
 /** @type {import('./$types').PageServerLoad} */
 export function load(event) {
 	return {
-		a: event.cookies.get('a')
+		encoding: event.cookies.get('encoding')
 	};
 }
diff --git a/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.svelte b/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.svelte
index 4e8537253..c7ce63378 100644
--- a/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.svelte
+++ b/packages/kit/test/apps/basics/src/routes/cookies/encoding/+page.svelte
@@ -4,5 +4,5 @@
 </script>
 
 Cookie: <span id="cookie-value">
-	{data.a}
+	{data.encoding}
 </span>
diff --git a/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js b/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js
index e17c5fcb9..e63aae2fb 100644
--- a/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js
+++ b/packages/kit/test/apps/basics/src/routes/cookies/encoding/not-decoded-twice/+server.js
@@ -3,6 +3,6 @@ import { redirect } from '@sveltejs/kit';
 /** @type {import('@sveltejs/kit').RequestHandler} */
 export const GET = (event) => {
 	const sneaky = 'teapot%2C%20jane%20austen';
-	event.cookies.set('a', sneaky);
+	event.cookies.set('encoding', sneaky);
 	throw redirect(303, '/cookies/encoding');
 };
diff --git a/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js b/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js
index f4f1d48a6..ebecc2e59 100644
--- a/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js
+++ b/packages/kit/test/apps/basics/src/routes/cookies/encoding/set/+server.js
@@ -3,6 +3,6 @@ import { redirect } from '@sveltejs/kit';
 /** @type {import('@sveltejs/kit').RequestHandler} */
 export const GET = (event) => {
 	const needsEncoding = 'teapot, jane austen';
-	event.cookies.set('a', needsEncoding);
+	event.cookies.set('encoding', needsEncoding);
 	throw redirect(303, '/cookies/encoding');
 };
diff --git a/packages/kit/test/apps/basics/src/routes/load/fetch-credentialed.json/+server.js b/packages/kit/test/apps/basics/src/routes/load/fetch-credentialed.json/+server.js
index 7536c51d8..a8ad1d6ff 100644
--- a/packages/kit/test/apps/basics/src/routes/load/fetch-credentialed.json/+server.js
+++ b/packages/kit/test/apps/basics/src/routes/load/fetch-credentialed.json/+server.js
@@ -3,6 +3,6 @@ import { json } from '@sveltejs/kit';
 /** @type {import('./$types').RequestHandler} */
 export function GET(event) {
 	return json({
-		name: event.locals.name
+		name: event.locals.name ?? 'Fail'
 	});
 }
diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js
index 7c7632120..7307c9211 100644
--- a/packages/kit/test/apps/basics/test/test.js
+++ b/packages/kit/test/apps/basics/test/test.js
@@ -1967,7 +1967,8 @@ test.describe('Actions', () => {
 	});
 });
 
-test.describe('Cookies API', () => {
+// Run in serial to not pollute the log with (correct) cookie warnings
+test.describe.serial('Cookies API', () => {
 	// there's a problem running these tests in the CI with webkit,
 	// since AFAICT the browser is using http://localhost and webkit won't
 	// set a `Secure` cookie on that. So we bail...
@@ -1994,18 +1995,6 @@ test.describe('Cookies API', () => {
 		expect(await span.innerText()).toContain('undefined');
 	});
 
-	test('cookies can be set with a path', async ({ page }) => {
-		await page.goto('/cookies/nested/a');
-		let span = page.locator('#cookie-value');
-		expect(await span.innerText()).toContain('teapot');
-		await page.goto('/cookies/nested/b');
-		span = page.locator('#cookie-value');
-		expect(await span.innerText()).toContain('undefined');
-		await page.goto('/cookies');
-		span = page.locator('#cookie-value');
-		expect(await span.innerText()).toContain('undefined');
-	});
-
 	test('more than one cookie can be set in one request', async ({ page }) => {
 		await page.goto('/cookies/set-more-than-one');
 		const span = page.locator('#cookie-value');
@@ -2043,4 +2032,16 @@ test.describe('Cookies API', () => {
 		await page.click('button#janeAusten');
 		await expect(page.locator('#cookie-value')).toHaveText('Jane Austen');
 	});
+
+	test('cookies can be set with a path', async ({ page }) => {
+		await page.goto('/cookies/nested/a');
+		let span = page.locator('#cookie-value');
+		expect(await span.innerText()).toContain('teapot');
+		await page.goto('/cookies/nested/b');
+		span = page.locator('#cookie-value');
+		expect(await span.innerText()).toContain('undefined');
+		await page.goto('/cookies');
+		span = page.locator('#cookie-value');
+		expect(await span.innerText()).toContain('undefined');
+	});
 });