Repository: sveltejs/kit (js)

Issue:
support autoscroll to non-ascii id
### Describe the problem

I'm using markdown to write some article in sveltekit,  header element auto generate anchor, like this: 
 `<h1 id="something-你好">something-你好<a ... /></h1>`
on page load, it will not auto scroll to h1 elelment, if it's id contains non ascii characters.

### Describe the proposed solution

`decodeURLComponent` before auto scroll to hash
https://github.com/sveltejs/kit/blob/master/packages/kit/src/runtime/client/client.js#L336
```js
const deep_linked = url.hash && document.getElementById(url.hash.slice(1));
```

change to 

```js
const deep_linked = url.hash && document.querySelector(decodeURIComponent(url.hash));
```

### Alternatives considered

_No response_

### Importance

would make my life easier

### Additional Information

_No response_

Pull request:
fix: handle non-ascii anchors when navigating
Closes #8277 

### 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. 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/ten-bats-retire.md b/.changeset/ten-bats-retire.md
new file mode 100644
index 000000000..15b0c8baf
--- /dev/null
+++ b/.changeset/ten-bats-retire.md
@@ -0,0 +1,5 @@
+---
+"@sveltejs/kit": patch
+---
+
+docs: fix typo
diff --git a/.changeset/ten-spiders-chew.md b/.changeset/ten-spiders-chew.md
new file mode 100644
index 000000000..84d166327
--- /dev/null
+++ b/.changeset/ten-spiders-chew.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: build error on layout with missing leaves
diff --git a/.changeset/twenty-taxis-nail.md b/.changeset/twenty-taxis-nail.md
new file mode 100644
index 000000000..fcc37f99a
--- /dev/null
+++ b/.changeset/twenty-taxis-nail.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: handle hash links with non-ASCII characters when navigating
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b08e334a2..df1e8e939 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -30,6 +30,14 @@ Entry points to be aware of are:
 - [`packages/kit/src/exports/vite`](https://github.com/sveltejs/kit/tree/master/packages/kit/src/exports/vite) - for all the Vite plugin related stuff
 - [`packages/adapter-[platform]`](https://github.com/sveltejs/kit/tree/master/packages) - for the various SvelteKit-provided adapters
 
+## Good first issues
+
+If you're looking for an issue to tackle to get familiar with the codebase and test suite, the [**low hanging fruit**](https://github.com/sveltejs/kit/issues?q=is%3Aissue+is%3Aopen+label%3A%22low+hanging+fruit%22) label contains issues that ought to be relatively straightforward to fix. Check to see if a PR already exists for an issue before working on it!
+
+Issues that have a clear solution but which _may_ be slightly more involved have the [**ready to implement**](https://github.com/sveltejs/kit/issues?q=is%3Aissue+is%3Aopen+label%3A%22ready+to+implement%22) label.
+
+Issues with the [**soon**](https://github.com/sveltejs/kit/issues?q=is%3Aissue+is%3Aopen+milestone%3Asoon) milestone are higher priority than issues with the [**later**](https://github.com/sveltejs/kit/issues?q=is%3Aissue+is%3Aopen+milestone%3Alater+) label (though PRs for 'later' issues are still welcome, especially if you're affected by them).
+
 ## Testing
 
 Run `pnpm test` to run the tests from all subpackages. Browser tests live in subdirectories of `packages/kit/test` such as `packages/kit/test/apps/basics`.
@@ -58,15 +66,15 @@ If you would like to test local changes to Vite or another dependency, you can b
 
 ```jsonc
 {
-	// ...
-	"dependencies": {
-		"vite": "^3.1.0"
-	},
-	"pnpm": {
-		"overrides": {
-			"vite": "link:../path/to/vite/packages/vite"
-		}
-	}
+  // ...
+  "dependencies": {
+    "vite": "^4.0.0"
+  },
+  "pnpm": {
+    "overrides": {
+      "vite": "link:../path/to/vite/packages/vite"
+    }
+  }
 }
 ```
 
diff --git a/documentation/docs/20-core-concepts/20-load.md b/documentation/docs/20-core-concepts/20-load.md
index 7095cc22f..e865bcc34 100644
--- a/documentation/docs/20-core-concepts/20-load.md
+++ b/documentation/docs/20-core-concepts/20-load.md
@@ -417,6 +417,8 @@ export function load({ locals }) {
 
 > Make sure you're not catching the thrown redirect, which results in a noop.
 
+In the browser, you can also navigate programmatically outside of a `load` function using [`goto`](modules#$app-navigation-goto) from [`$app.navigation`](modules#$app-navigation).
+
 ## Promise unwrapping
 
 Top-level promises will be awaited, which makes it easy to return multiple promises without creating a waterfall:
diff --git a/documentation/docs/25-build-and-deploy/50-adapter-static.md b/documentation/docs/25-build-and-deploy/50-adapter-static.md
index d34bcc73b..0c688a506 100644
--- a/documentation/docs/25-build-and-deploy/50-adapter-static.md
+++ b/documentation/docs/25-build-and-deploy/50-adapter-static.md
@@ -137,7 +137,7 @@ export default {
 
 When operating in SPA mode, you can omit the [`prerender`](page-options#prerender) option from your root layout (or set it to `false`, its default value), and only pages that have the `prerender` option set will be prerendered at build time.
 
-SvelteKit will still crawl your app's entry points looking for prerenderable pages. If `svelte-kit build` fails because of pages that can't be loaded outside the browser, you can set `config.kit.prerender.entries` to `[]` to prevent this from happening. (Setting `config.kit.prerender.enabled` to `false` also has this effect, but would prevent the fallback page from being generated.)
+SvelteKit will still crawl your app's entry points looking for prerenderable pages. If `svelte-kit build` fails because of pages that can't be loaded outside the browser, you can set `config.kit.prerender.entries` to `[]` to prevent this from happening.
 
 You can also add turn off prerendering only to parts of your app, if you want other parts to be prerendered.
 
diff --git a/package.json b/package.json
index 6dd9a7d7e..c9236e32f 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
 		"tiny-glob": "^0.2.9",
 		"typescript": "^4.9.4"
 	},
-	"packageManager": "pnpm@7.26.1",
+	"packageManager": "pnpm@7.26.2",
 	"engines": {
 		"pnpm": "^7.0.0"
 	},
diff --git a/packages/adapter-vercel/CHANGELOG.md b/packages/adapter-vercel/CHANGELOG.md
index e7bb137ad..14e05a283 100644
--- a/packages/adapter-vercel/CHANGELOG.md
+++ b/packages/adapter-vercel/CHANGELOG.md
@@ -1,5 +1,14 @@
 # @sveltejs/adapter-vercel
 
+## 1.0.6
+
+### Patch Changes
+
+- fix: add trailing slash -> no trailing slash redirect for prerendered pages ([#8766](https://github.com/sveltejs/kit/pull/8766))
+
+- Updated dependencies [[`438e4318`](https://github.com/sveltejs/kit/commit/438e4318e96f3e192e273b95d20ee8f590e99829)]:
+  - @sveltejs/kit@1.3.4
+
 ## 1.0.5
 
 ### Patch Changes
diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js
index 529225d7c..47d384ee3 100644
--- a/packages/adapter-vercel/index.js
+++ b/packages/adapter-vercel/index.js
@@ -193,16 +193,24 @@ function static_vercel_config(builder) {
 	}
 
 	for (const [path, page] of builder.prerendered.pages) {
-		if (path.endsWith('/') && path !== '/') {
+		let overrides_path = path.slice(1);
+
+		if (path !== '/') {
+			/** @type {string | undefined} */
+			let counterpart_route = path + '/';
+
+			if (path.endsWith('/')) {
+				counterpart_route = path.slice(0, -1);
+				overrides_path = path.slice(1, -1);
+			}
+
 			prerendered_redirects.push(
-				{ src: path, dest: path.slice(0, -1) },
-				{ src: path.slice(0, -1), status: 308, headers: { Location: path } }
+				{ src: path, dest: counterpart_route },
+				{ src: counterpart_route, status: 308, headers: { Location: path } }
 			);
-
-			overrides[page.file] = { path: path.slice(1, -1) };
-		} else {
-			overrides[page.file] = { path: path.slice(1) };
 		}
+
+		overrides[page.file] = { path: overrides_path };
 	}
 
 	return {
diff --git a/packages/adapter-vercel/package.json b/packages/adapter-vercel/package.json
index b87b33985..159f4d45f 100644
--- a/packages/adapter-vercel/package.json
+++ b/packages/adapter-vercel/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@sveltejs/adapter-vercel",
-	"version": "1.0.5",
+	"version": "1.0.6",
 	"repository": {
 		"type": "git",
 		"url": "https://github.com/sveltejs/kit",
diff --git a/packages/kit/CHANGELOG.md b/packages/kit/CHANGELOG.md
index 1ccc0b796..ca41d03dc 100644
--- a/packages/kit/CHANGELOG.md
+++ b/packages/kit/CHANGELOG.md
@@ -1,5 +1,17 @@
 # @sveltejs/kit
 
+## 1.3.4
+
+### Patch Changes
+
+- chore: bump devalue ([#8789](https://github.com/sveltejs/kit/pull/8789))
+
+## 1.3.3
+
+### Patch Changes
+
+- fix: forward `process.env` to child process ([#8777](https://github.com/sveltejs/kit/pull/8777))
+
 ## 1.3.2
 
 ### Patch Changes
diff --git a/packages/kit/package.json b/packages/kit/package.json
index f2ad02c66..1d98a5ba8 100644
--- a/packages/kit/package.json
+++ b/packages/kit/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "@sveltejs/kit",
-	"version": "1.3.2",
+	"version": "1.3.4",
 	"repository": {
 		"type": "git",
 		"url": "https://github.com/sveltejs/kit",
@@ -13,7 +13,7 @@
 		"@sveltejs/vite-plugin-svelte": "^2.0.0",
 		"@types/cookie": "^0.5.1",
 		"cookie": "^0.5.0",
-		"devalue": "^4.2.2",
+		"devalue": "^4.2.3",
 		"esm-env": "^1.0.0",
 		"kleur": "^4.1.5",
 		"magic-string": "^0.27.0",
diff --git a/packages/kit/src/core/postbuild/analyse.js b/packages/kit/src/core/postbuild/analyse.js
index 4a1cd2600..fe99fd43c 100644
--- a/packages/kit/src/core/postbuild/analyse.js
+++ b/packages/kit/src/core/postbuild/analyse.js
@@ -55,9 +55,9 @@ async function analyse({ manifest_path, env }) {
 	for (const loader of manifest._.nodes) {
 		const node = await loader();
 
-		metadata.nodes.push({
+		metadata.nodes[node.index] = {
 			has_server_load: node.server?.load !== undefined
-		});
+		};
 	}
 
 	// analyse routes
diff --git a/packages/kit/src/core/sync/write_client_manifest.js b/packages/kit/src/core/sync/write_client_manifest.js
index 06c32d8a4..9137b9f86 100644
--- a/packages/kit/src/core/sync/write_client_manifest.js
+++ b/packages/kit/src/core/sync/write_client_manifest.js
@@ -38,7 +38,6 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
 
 	/** @type {Map<import('types').PageNode, number>} */
 	const indices = new Map();
-
 	const nodes = manifest_data.nodes
 		.map((node, i) => {
 			indices.set(node, i);
@@ -64,6 +63,7 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
 					if (route.leaf) {
 						if (metadata) {
 							const i = /** @type {number} */ (indices.get(route.leaf));
+
 							leaf_has_server_load = metadata[i].has_server_load;
 						} else if (route.leaf.server) {
 							leaf_has_server_load = true;
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index e74085ab3..7c48c8f6f 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -343,7 +343,7 @@ export function create_client({ target, base }) {
 			}
 
 			if (autoscroll) {
-				const deep_linked = url.hash && document.getElementById(url.hash.slice(1));
+				const deep_linked = url.hash && document.querySelector(decodeURIComponent(url.hash));
 				if (scroll) {
 					scrollTo(scroll.x, scroll.y);
 				} else if (deep_linked) {
diff --git a/packages/kit/src/utils/fork.js b/packages/kit/src/utils/fork.js
index 1cffc54a3..58ed2dcb5 100644
--- a/packages/kit/src/utils/fork.js
+++ b/packages/kit/src/utils/fork.js
@@ -39,6 +39,7 @@ export function forked(module, callback) {
 			const child = child_process.fork(fileURLToPath(module), {
 				stdio: 'inherit',
 				env: {
+					...process.env,
 					SVELTEKIT_FORK: 'true'
 				},
 				serialization: 'advanced'
diff --git a/packages/kit/types/ambient.d.ts b/packages/kit/types/ambient.d.ts
index 8a8103795..474cd297b 100644
--- a/packages/kit/types/ambient.d.ts
+++ b/packages/kit/types/ambient.d.ts
@@ -237,7 +237,7 @@ declare module '$app/navigation' {
 	 * Programmatically imports the code for routes that haven't yet been fetched.
 	 * Typically, you might call this to speed up subsequent navigation.
 	 *
-	 * You can specify routes by any matching pathname such as `/about` (to match `src/routes/about.svelte`) or `/blog/*` (to match `src/routes/blog/[slug].svelte`).
+	 * You can specify routes by any matching pathname such as `/about` (to match `src/routes/about/+page.svelte`) or `/blog/*` (to match `src/routes/blog/[slug]/+page.svelte`).
 	 *
 	 * Unlike `preloadData`, this won't call `load` functions.
 	 * Returns a Promise that resolves when the modules have been imported.
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index d7f0fb599..761d4aec9 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -506,7 +506,7 @@ export interface KitConfig {
 	typescript?: {
 		/**
 		 * A function that allows you to edit the generated `tsconfig.json`. You can mutate the config (recommended) or return a new one.
-		 * This is useful for — to example — extend a shared `tsconfig.json` in a monorepo root
+		 * This is useful for extending a shared `tsconfig.json` in a monorepo root, for example.
 		 * @default (config) => config
 		 */
 		config?: (config: Record<string, any>) => Record<string, any> | void;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a1b2e8931..48a6d69b4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -265,7 +265,7 @@ importers:
       '@types/sade': ^1.7.4
       '@types/set-cookie-parser': ^2.4.2
       cookie: ^0.5.0
-      devalue: ^4.2.2
+      devalue: ^4.2.3
       esm-env: ^1.0.0
       kleur: ^4.1.5
       magic-string: ^0.27.0
@@ -286,7 +286,7 @@ importers:
       '@sveltejs/vite-plugin-svelte': 2.0.0_svelte@3.55.1+vite@4.0.4
       '@types/cookie': 0.5.1
       cookie: 0.5.0
-      devalue: 4.2.2
+      devalue: 4.2.3
       esm-env: 1.0.0
       kleur: 4.1.5
       magic-string: 0.27.0
@@ -2098,8 +2098,8 @@ packages:
     resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==}
     engines: {node: '>=8'}
 
-  /devalue/4.2.2:
-    resolution: {integrity: sha512-Pkwd8qrI9O20VJ14fBNHu+on99toTNZFbgWRpZbC0zbDXpnE2WHYcrC1fHhMsF/3Ee+2yaW7vEujAT7fCYgqrA==}
+  /devalue/4.2.3:
+    resolution: {integrity: sha512-JG6Q248aN0pgFL57e3zqTVeFraBe+5W2ugvv1mLXsJP6YYIYJhRZhAl7QP8haJrqob6X10F9NEkuCvNILZTPeQ==}
     dev: false
 
   /diff/5.1.0:


Test patch:
diff --git a/packages/kit/test/apps/basics/src/routes/anchor/+page.svelte b/packages/kit/test/apps/basics/src/routes/anchor/+page.svelte
index 0d606cd72..479a2083d 100644
--- a/packages/kit/test/apps/basics/src/routes/anchor/+page.svelte
+++ b/packages/kit/test/apps/basics/src/routes/anchor/+page.svelte
@@ -1,5 +1,6 @@
 <h1>Welcome to a test project</h1>
 <a id="scroll-anchor" href="#last-anchor-2">Bottom of this page</a>
+<a id="non-ascii-anchor" href="/anchor/anchor#go-to-encöded">Anchor demo (non-ASCII)</a>
 <a id="first-anchor" href="/anchor/anchor#go-to-element">Anchor demo (first)</a>
 <div>Spacing</div>
 <a id="second-anchor" href="/anchor/anchor#go-to-element">Anchor demo (second)</a>
diff --git a/packages/kit/test/apps/basics/src/routes/anchor/anchor/+page.svelte b/packages/kit/test/apps/basics/src/routes/anchor/anchor/+page.svelte
index 57406e6d3..1289d74e6 100644
--- a/packages/kit/test/apps/basics/src/routes/anchor/anchor/+page.svelte
+++ b/packages/kit/test/apps/basics/src/routes/anchor/anchor/+page.svelte
@@ -2,3 +2,6 @@
 <div style="height: 180vh; background-color: peru;">
 	<p id="go-to-element">The browser scrolls to me</p>
 </div>
+<div style="height: 180vh; background-color: tomato;">
+	<p id="go-to-encöded">The browser scrolls to me</p>
+</div>
diff --git a/packages/kit/test/apps/basics/test/cross-platform/client.test.js b/packages/kit/test/apps/basics/test/cross-platform/client.test.js
index 42028b930..f92e08549 100644
--- a/packages/kit/test/apps/basics/test/cross-platform/client.test.js
+++ b/packages/kit/test/apps/basics/test/cross-platform/client.test.js
@@ -214,6 +214,16 @@ test.describe('Scrolling', () => {
 		expect(await in_view('#go-to-element')).toBe(true);
 	});
 
+	test('url-supplied non-ascii anchor works on navigation to page', async ({
+		page,
+		in_view,
+		clicknav
+	}) => {
+		await page.goto('/anchor');
+		await clicknav('#non-ascii-anchor');
+		expect(await in_view('#go-to-encöded')).toBe(true);
+	});
+
 	test('url-supplied anchor works when navigated from scrolled page', async ({
 		page,
 		clicknav,
diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js
index 748253030..a375d7621 100644
--- a/packages/kit/test/apps/basics/test/server.test.js
+++ b/packages/kit/test/apps/basics/test/server.test.js
@@ -164,8 +164,7 @@ test.describe('Errors', () => {
 		expect(await response.text()).toMatch('PUT method not allowed');
 	});
 
-	// TODO re-enable this if https://github.com/vitejs/vite/issues/7046 is implemented
-	test.skip('error evaluating module', async ({ request }) => {
+	test('error evaluating module', async ({ request }) => {
 		const response = await request.get('/errors/init-error-endpoint');
 
 		expect(response.status()).toBe(500);