Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent onhashchange detection and hash = "" in $page.url when a hash is present #3205

Closed
Co1eCas3 opened this issue Jan 4, 2022 · 3 comments · Fixed by #3273
Closed
Labels
bug Something isn't working p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc. router
Milestone

Comments

@Co1eCas3
Copy link

Co1eCas3 commented Jan 4, 2022

Describe the bug

Things that don't work:

  1. $page.url.hash is "" when navigating directly to a URL with a hash.
  2. $page store does not cause component updates when clicking an anchor that has an href with hash
    i. <a href='page/with#hash'>Link</a>

Things that are working:

  1. component does react to $page store if using goto
    i. <a on:click={() => goto('page/with#hash')>Link </a>
  2. $page store does react if navigating away from a hash URL with an anchor tag.

Reproduction

https://stackblitz.com/edit/sveltekit-jrgcbe?devtoolsheight=33&file=src/routes/test/index.svelte

Logs

In my code:

$: browser && console.log(window.location);
$: console.log('logging $page.url: ', $page.url);

Logs:

Location {ancestorOrigins: DOMStringList, href: 'http://localhost:3000/user/bands#new', origin: 'http://localhost:3000', protocol: 'http:', host: 'localhost:3000', …}
ancestorOrigins: DOMStringList {length: 0}
assign: ƒ assign()
hash: "#new"
host: "localhost:3000"
hostname: "localhost"
href: "http://localhost:3000/user/bands#new"
origin: "http://localhost:3000"
pathname: "/user/bands"
port: "3000"
protocol: "http:"
reload: ƒ reload()
replace: ƒ replace()
search: ""
toString: ƒ toString()
valueOf: ƒ valueOf()
Symbol(Symbol.toPrimitive): undefined
[[Prototype]]: Location
bands.svelte? [sm]:15 logging $page.url:  
URL {origin: 'http://localhost:3000', protocol: 'http:', username: '', password: '', host: 'localhost:3000', …}
hash: ""
host: "localhost:3000"
hostname: "localhost"
href: "http://localhost:3000/user/bands"
origin: "http://localhost:3000"
password: ""
pathname: "/user/bands"
port: "3000"
protocol: "http:"
search: ""
searchParams: URLSearchParams {}
username: ""
[[Prototype]]: URL


### System Info

```shell
npx envinfo --system --binaries --browsers --npmPackages "{svelte,@sveltejs/*,vite}" 
npx: installed 1 in 1.909s

  System:
    OS: Windows 10 10.0.19043
    CPU: (8) x64 Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz
    Memory: 6.00 GB / 23.63 GB
  Binaries:
    Node: 14.17.0 - C:\Program Files\nodejs\node.EXE
    npm: 6.14.13 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (96.0.1054.62)
    Internet Explorer: 11.0.19041.1202
  npmPackages:
    @sveltejs/adapter-auto: ^1.0.0-next.7 => 1.0.0-next.7
    @sveltejs/kit: ^1.0.0-next.215 => 1.0.0-next.215
    svelte: ^3.44.3 => 3.44.3

Severity

serious, but I can work around it

Additional Information

No response

@bluwy
Copy link
Member

bluwy commented Jan 4, 2022

Likely a regression from #3177. That PR skips router navigation for anchor tags that links to a hash on the same page. We'll need to figure out how to update the $page store from there.

@bluwy bluwy added bug Something isn't working p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc. router labels Jan 4, 2022
@benmccann benmccann added this to the 1.0 milestone Jan 4, 2022
@nhe23
Copy link
Contributor

nhe23 commented Jan 9, 2022

@bluwy this will only solve half of this issue. When navigating directly to the URL the client site router is not called, so setting the store there won't help in this case.
After some investigation I found out that the code which sets the $page store is called but the URL object that is passed to it has an empty string for hash (tested in dev mode & built version with adapter-node). This is logical as the fragment identifier # and anything after it is never sent to the server by the browser.

Adding this to the start function in the renderer would solve this:

	async start({ status, error, nodes, url, params }) {
		/** @type {Array<import('./types').BranchNode | undefined>} */
		const branch = [];

		/** @type {Record<string, any>} */
		let stuff = {};

		/** @type {import('./types').NavigationResult | undefined} */
		let result;

		let error_args;

+		// url.hash is empty when coming from the server
+		url.hash = window.location.hash;

I'm still looking into how to best set the page store in the router. I'll create a PR as soon as I have a feasible solution for this.

@bluwy
Copy link
Member

bluwy commented Jan 11, 2022

@nhe23 Excellent work! This was fixed rather quickly before I had a chance to reply, but your proposal and PR LGTM. Thanks for tackling this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc. router
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants