Repository: sveltejs/kit (js)

Issue:
Prefetch repeatedly refetching after a 40x from a route
### Describe the bug

SvelteKit repeatedly tries to prefetch a page that throws 40x http codes. 
Which should not be the case for 401 and 403, as they are typically used for restricting access to content.

This also adds the issue of `hooks.server.ts` being spammed with each request.

### Reproduction

https://github.com/Curstantine/sveltekit-prefetch-4xx-repeat

### Logs

_No response_

### System Info

```Shell
System:
    OS: Linux 6.0 undefined
    CPU: (4) x64 Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
    Memory: 4.82 GB / 7.65 GB
    Container: Yes
    Shell: 3.5.1 - /bin/fish
  Binaries:
    Node: 19.3.0 - /usr/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 8.19.2 - /usr/bin/npm
  npmPackages:
    @sveltejs/adapter-auto: ^1.0.0 => 1.0.0 
    @sveltejs/kit: ^1.0.0 => 1.0.1 
    svelte: ^3.54.0 => 3.55.0 
    vite: ^4.0.0 => 4.0.3
```


### Severity

annoyance

### Additional Information

_No response_

Pull request description:
fix: warn when preload fails
closes #8301
closes #8476

### 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.
- [ ] 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. Changesets that add features should be `minor` and those that fix bugs should be `patch`. Please prefix changeset messages with `feat:`, `fix:`, or `chore:`.


Patch:
diff --git a/.changeset/loud-comics-stare.md b/.changeset/loud-comics-stare.md
new file mode 100644
index 000000000..d917da642
--- /dev/null
+++ b/.changeset/loud-comics-stare.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: warn after failed data preloads in dev
diff --git a/.changeset/lucky-toys-help.md b/.changeset/lucky-toys-help.md
new file mode 100644
index 000000000..24b3b3fd6
--- /dev/null
+++ b/.changeset/lucky-toys-help.md
@@ -0,0 +1,5 @@
+---
+'create-svelte': patch
+---
+
+fix: use new locator API to improve demo test
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index bcf81c2b7..aef957d74 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -1256,7 +1256,22 @@ export function create_client({ target }) {
 			if (!options.reload) {
 				if (priority <= options.preload_data) {
 					const intent = get_navigation_intent(/** @type {URL} */ (url), false);
-					if (intent) preload_data(intent);
+					if (intent) {
+						if (__SVELTEKIT_DEV__) {
+							preload_data(intent).then((result) => {
+								if (result.type === 'loaded' && result.state.error) {
+									console.warn(
+										`Preloading data for ${intent.url.pathname} failed with the following error: ${result.state.error.message}\n` +
+											'If this error is transient, you can ignore it. Otherwise, consider disabling preloading for this route. ' +
+											'This route was preloaded due to a data-sveltekit-preload-data attribute. ' +
+											'See https://kit.svelte.dev/docs/link-options for more info'
+									);
+								}
+							});
+						} else {
+							preload_data(intent);
+						}
+					}
 				} else if (priority <= options.preload_code) {
 					preload_code(get_url_path(/** @type {URL} */ (url)));
 				}
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index 721aa4cbd..5aeff376a 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -304,6 +304,8 @@ export interface KitConfig {
 	 * > When `mode` is `'auto'`, SvelteKit will use nonces for dynamically rendered pages and hashes for prerendered pages. Using nonces with prerendered pages is insecure and therefore forbidden.
 	 *
 	 * > Note that most [Svelte transitions](https://svelte.dev/tutorial/transition) work by creating an inline `<style>` element. If you use these in your app, you must either leave the `style-src` directive unspecified or add `unsafe-inline`.
+	 *
+	 * If this level of configuration is insufficient and you have more dynamic requirements, you can use the [`handle` hook](https://kit.svelte.dev/docs/hooks#server-hooks-handle) to roll your own CSP.
 	 */
 	csp?: {
 		/**


Test patch:
diff --git a/packages/create-svelte/shared/+playwright+default/tests/test.ts b/packages/create-svelte/shared/+playwright+default/tests/test.ts
index 38b7f95bd..09d2c0346 100644
--- a/packages/create-svelte/shared/+playwright+default/tests/test.ts
+++ b/packages/create-svelte/shared/+playwright+default/tests/test.ts
@@ -2,5 +2,5 @@ import { expect, test } from '@playwright/test';
 
 test('about page has expected h1', async ({ page }) => {
 	await page.goto('/about');
-	await expect(page.locator('h1')).toHaveText('About this app');
+	await expect(page.getByRole('heading', { name: 'About this app' })).toBeVisible();
 });
diff --git a/packages/create-svelte/shared/+playwright+skeleton/tests/test.ts b/packages/create-svelte/shared/+playwright+skeleton/tests/test.ts
index 4e579377e..5816be413 100644
--- a/packages/create-svelte/shared/+playwright+skeleton/tests/test.ts
+++ b/packages/create-svelte/shared/+playwright+skeleton/tests/test.ts
@@ -2,5 +2,5 @@ import { expect, test } from '@playwright/test';
 
 test('index page has expected h1', async ({ page }) => {
 	await page.goto('/');
-	expect(await page.textContent('h1')).toBe('Welcome to SvelteKit');
+	await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible();
 });
diff --git a/packages/create-svelte/shared/+playwright+skeletonlib/tests/test.ts b/packages/create-svelte/shared/+playwright+skeletonlib/tests/test.ts
index 4e579377e..5816be413 100644
--- a/packages/create-svelte/shared/+playwright+skeletonlib/tests/test.ts
+++ b/packages/create-svelte/shared/+playwright+skeletonlib/tests/test.ts
@@ -2,5 +2,5 @@ import { expect, test } from '@playwright/test';
 
 test('index page has expected h1', async ({ page }) => {
 	await page.goto('/');
-	expect(await page.textContent('h1')).toBe('Welcome to SvelteKit');
+	await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible();
 });