Repository: sveltejs/kit (js)

Issue:
v1.3.5 broke the URL hash handling
### Describe the bug

I updated from SvelteKit v1.3.4 to v1.3.5 and started to get the following error:

<img width="1608" alt="Screenshot 2023-01-31 at 9 09 34" src="https://user-images.githubusercontent.com/3757314/215691220-031c54c2-8aa7-48c8-a69e-36e2635c77a5.png">

My auth provider (Keycloak) redirects back to my app after login with a URL hash. It seems that the following change in #8767 broke the hash handling:

<img width="1615" alt="Screenshot 2023-01-31 at 8 37 56" src="https://user-images.githubusercontent.com/3757314/215691668-52d23320-42f0-4233-b87c-3d735a4b71d5.png">


### Reproduction

See the bug description.

### Logs

_No response_

### System Info

```Shell
System:
    OS: macOS 13.2
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 394.70 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
Binaries:
    Node: 18.13.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 8.19.3 - /usr/local/bin/npm
Browsers:
    Chrome: 109.0.5414.119
    Firefox: 109.0
    Safari: 16.3
```


### Severity

blocking an upgrade

### Additional Information

_No response_

Pull request description:
handle special chars in anchors when navigating
closes #8804

### 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/hip-eggs-raise.md b/.changeset/hip-eggs-raise.md
new file mode 100644
index 000000000..3220a0bef
--- /dev/null
+++ b/.changeset/hip-eggs-raise.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+fix: handle anchors with special chars when navigating
diff --git a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
index 94a050257..549740268 100644
--- a/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
+++ b/documentation/docs/25-build-and-deploy/90-adapter-vercel.md
@@ -69,7 +69,7 @@ Since all of these variables are unchanged between build time and run time when
 
 ### Vercel functions
 
-Vercel functions contained in the `/api` directory at the project's root will _not_ be included in the deployment — these should be implemented as [server endpoints](https://kit.svelte.dev/docs/routing#server) in your SvelteKit app.
+If you have Vercel functions contained in the `api` directory at the project's root, any requests for `/api/*` will _not_ be handled by SvelteKit. You should implement these as [API routes](https://kit.svelte.dev/docs/routing#server) in your SvelteKit app instead, unless you need to use a non-JavaScript language in which case you will need to ensure that you don't have any `/api/*` routes in your SvelteKit app.
 
 ### Node version
 
@@ -79,4 +79,4 @@ Projects created before a certain date will default to using Node 14, while Svel
 
 ### Accessing the file system
 
-You can't access the file system through methods like `fs.readFileSync` in Serverless/Edge environments. If you need to access files that way, do that during building the app through [prerendering](https://kit.svelte.dev/docs/page-options#prerender). If you have a blog for example and don't want to manage your content through a CMS, then you need to prerender the content (or prerender the endpoint from which you get it) and redeploy your blog everytime you add new content.
\ No newline at end of file
+You can't access the file system through methods like `fs.readFileSync` in Serverless/Edge environments. If you need to access files that way, do that during building the app through [prerendering](https://kit.svelte.dev/docs/page-options#prerender). If you have a blog for example and don't want to manage your content through a CMS, then you need to prerender the content (or prerender the endpoint from which you get it) and redeploy your blog everytime you add new content.
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 7c48c8f6f..0369e2710 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -343,7 +343,8 @@ export function create_client({ target, base }) {
 			}
 
 			if (autoscroll) {
-				const deep_linked = url.hash && document.querySelector(decodeURIComponent(url.hash));
+				const deep_linked =
+					url.hash && document.getElementById(decodeURIComponent(url.hash.slice(1)));
 				if (scroll) {
 					scrollTo(scroll.x, scroll.y);
 				} else if (deep_linked) {


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 479a2083d..c6c309881 100644
--- a/packages/kit/test/apps/basics/src/routes/anchor/+page.svelte
+++ b/packages/kit/test/apps/basics/src/routes/anchor/+page.svelte
@@ -1,6 +1,7 @@
 <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="special-char-anchor" href="/anchor/anchor#go-to-.=">Anchor demo (special characters)</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 1289d74e6..2cf545d88 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
@@ -5,3 +5,6 @@
 <div style="height: 180vh; background-color: tomato;">
 	<p id="go-to-encöded">The browser scrolls to me</p>
 </div>
+<div style="height: 180vh; background-color: honeydew;">
+	<p id="go-to-.=" class="special-char-id">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 f92e08549..6ab72a150 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
@@ -224,6 +224,16 @@ test.describe('Scrolling', () => {
 		expect(await in_view('#go-to-encöded')).toBe(true);
 	});
 
+	test('url-supplied anchor with special characters works on navigation to page', async ({
+		page,
+		in_view,
+		clicknav
+	}) => {
+		await page.goto('/anchor');
+		await clicknav('#special-char-anchor');
+		expect(await in_view('.special-char-id')).toBe(true);
+	});
+
 	test('url-supplied anchor works when navigated from scrolled page', async ({
 		page,
 		clicknav,