Here's a repo reproducing the issue, which I'm currently only seeing in Firefox: https://github.com/mhkeller/anchor-test
When I go to a page that has an anchor tag like localhost:3000/#link-5, it will initially load at the correct page height but then jump to the top. In Chrome and Safari, the page stays where it's supposed to.

I've found a possibly related bug across all browsers which is that if I have a page at localhost:3000/my-page and on that page I have an anchor link like <a href="#section2>section 2</a>, when I click on it, instead of going to localhost:3000/my-page#section2 I'll be taken to localhost:3000/#section2.
I've updated my test repo to also show this bug as well. Check out the instructions in the README to reproduce under Reproduce bug two
I've set up a barebones HTML page to show the expected behavior at: https://github.com/mhkeller/anchor-test-two
This may be because the handle_click function doesn't seem to have a use case for handling hashes. That function says it's adapted from page.js, whose analogous function does do a check for el.hash here: https://github.com/visionmedia/page.js/blob/5648ef91a076d4caf20c54287082c2507ca5ff6a/page.js#L1044
I tried putting in similar code by modifying my test repo but I must not be triggering the build properly since I can't get my changes to show up.
I just found this issue when coming to report a slightly different issue with anchor tags. Reported here: #341 I reused much of the test repo. Thanks @mhkeller !
I'm starting to dig on this issue right now.
@mhkeller The check you are referring to may solve this issue, but it isn't enough. Even if it doesn't treat hash links as route changes, it still presents the other issue already mentioned by @alizauf, that I'm digging on.
Shouldn't hash be derived from target?
https://github.com/sveltejs/sapper/blob/7aa3e90f8788fd2be695627272b51c13df3ea563/runtime/src/app/app.ts#L200
It's not being passed in goto
@mhkeller, can you test again with the new version? I believe that the PR from DayBr3ak solves this issue as well.
This is still an issue with the latest version when first loading a page with an anchor. From looking at this, my initial idea is to just change this:
and switch noscroll from false to true - so we don't mess up the initial scroll position that the browser takes care of on its own. It _looks_ like this works but I have no idea whether it breaks anything.
I've found a possibly related bug across all browsers which is that if I have a page at
localhost:3000/my-pageand on that page I have an anchor link like<a href="#section2>section 2</a>, when I click on it, instead of going tolocalhost:3000/my-page#section2I'll be taken tolocalhost:3000/#section2.I've updated my test repo to also show this bug as well. Check out the instructions in the README to reproduce under Reproduce bug two
I've set up a barebones HTML page to show the expected behavior at: https://github.com/mhkeller/anchor-test-two
Based on this thread I would assume that I'm not supposed to be seeing the behavior described in this comment, where clicking a "pure id" anchor tag of the form <a href="#id-on-same-page">Go</a> goes all the way back to the root. But I am.
This is with Sapper 0.27 and Svelte 3.0 – anyone know what might be causing it? Or was this half of the problem just never fixed?
is this the baseUrl issue? (search for it)
Yeah it is. It is indeed currently intended that an anchor like that takes you back to the root, and we realize that's not convenient, and there's an issue where we're trying to figure out what to do about it.
Ah I see.
For anyone else coming here, the issue is #904
I have the same issue with fragment in URL, when I am trying to use it:
when clicking on page with path /example on this element a(href="#comparePlans") brings to root path /#comparePlans. What's the resolution here? It is still not solved as I understand?
cheers!
Its seems that this workaround on https://github.com/sveltejs/sapper/issues/904 may help, with adjustments from the next comment.
the workaround of course doesn't hit shadow doms in web components and such..so still largely broken for us.
couldn't sapper just tag onto something like rel="internal" to avoid processing the link as a route and instead treat it as a smooth scroll internal link?
Another workaround for the time being might be to hijack and prevent the click event, using a native JS scrollIntoView instead?
<script>
function scrollTo({ target }) {
document.querySelector(target.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
}
</script>
<a href="#section-1" on:click|preventDefault={scrollTo}>Section 1</a>
<div id="section-1">...</div>
This way server-rendered/static apps will still have the correct anchor href without JavaScript, but we should be able to prevent Sapper from stepping in and hijacking the link?
@adamduncan sounds good. Did it work for you?
@zolotokrylin There are a couple of related-but-different issues being discussed here. This scrollIntoView workaround deals with trying to link to #hash links on the same page, but instead being sent back to the site root (https://github.com/sveltejs/sapper/issues/331#issuecomment-540914240).
One workaround is to prepend the window.location to all hash links (#904), therefore linking users to the same page. The alternate approach I've suggested (REPL here) will suppress the navigation from happening entirely, and instead use native JS methods to scroll the element into view. (One might also want to manually update the URL with the correct hash using history.pushState.)
Any word on getting this fix? I bashed a couple of the answers here together and got this working, I like this as a temporary solution (for me anyways).
import { onMount } from 'svelte'
onMount(() => {
document.querySelectorAll('a').forEach(a => {
if (!a.hash || !document.querySelectorAll(a.hash).length) return
a.addEventListener('click', event => {
event.preventDefault()
window.location.hash = event.target.getAttribute('href')
event.target.scrollIntoView()
})
})
})
a simple workaround is to put the local path with the href, for example if the path is http://localhost:3000/product/foo
instead of
<a href="#anchor"> link to same page </a>
we use
<a href="product/foo#anchor"> link to same page </a>
this is working on sapper: 0.28.10 and svelte: 3.29.4 on localhost, didn't try yet on a live server
Most helpful comment
Any word on getting this fix? I bashed a couple of the answers here together and got this working, I like this as a temporary solution (for me anyways).