Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Sapper treats anchor tag clicks as route changes #331

Closed
mhkeller opened this issue Aug 1, 2018 · 20 comments · Fixed by #692
Closed

Sapper treats anchor tag clicks as route changes #331

mhkeller opened this issue Aug 1, 2018 · 20 comments · Fixed by #692
Labels

Comments

@mhkeller
Copy link

mhkeller commented Aug 1, 2018

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.

screenshot

@mhkeller mhkeller changed the title Links to anchor tags don't stay in Firefox Inconsistent anchor link behavior Aug 5, 2018
@mhkeller
Copy link
Author

mhkeller commented Aug 5, 2018

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

@mhkeller
Copy link
Author

mhkeller commented Aug 5, 2018

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.

@mhkeller mhkeller changed the title Inconsistent anchor link behavior Sapper tries to route anchor tag clicks as route changes Aug 5, 2018
@mhkeller mhkeller changed the title Sapper tries to route anchor tag clicks as route changes Sapper treats anchor tag clicks as route changes Aug 5, 2018
@alizauf
Copy link

alizauf commented Aug 6, 2018

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 !

@paulocoghi
Copy link

I'm starting to dig on this issue right now.

@paulocoghi
Copy link

paulocoghi commented Aug 6, 2018

@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.

@thgh
Copy link
Contributor

thgh commented May 12, 2019

Shouldn't hash be derived from target?

if (hash) {

It's not being passed in goto

@paulocoghi
Copy link

@mhkeller, can you test again with the new version? I believe that the PR from DayBr3ak solves this issue as well.

@Conduitry
Copy link
Member

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:

if (target) return navigate(target, uid, false, hash);

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.

Rich-Harris added a commit that referenced this issue May 21, 2019
leave anchor scrolling on initial load to browser
@Aias
Copy link

Aias commented Oct 11, 2019

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

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?

@swyxio
Copy link

swyxio commented Oct 11, 2019

is this the baseUrl issue? (search for it)

@Conduitry
Copy link
Member

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.

@Aias
Copy link

Aias commented Oct 11, 2019

Ah I see.

For anyone else coming here, the issue is #904

@zolotokrylin
Copy link

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!

@paulocoghi
Copy link

Its seems that this workaround on #904 may help, with adjustments from the next comment.

@JoshuaJarman
Copy link

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?

@adamduncan
Copy 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?

@zolotokrylin
Copy link

@adamduncan sounds good. Did it work for you?

@adamduncan
Copy link

adamduncan commented Jul 20, 2020

@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 (#331 (comment)).

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.)

@ryanfiller
Copy link

ryanfiller commented Oct 11, 2020

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()
    })
  })
})

@espansione8
Copy link

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.