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

anchors do not work #5359

Closed
syffs opened this issue Mar 24, 2019 · 38 comments
Closed

anchors do not work #5359

syffs opened this issue Mar 24, 2019 · 38 comments
Assignees

Comments

@syffs
Copy link

syffs commented Mar 24, 2019

Version

v2.5.1

Reproduction link

https://codesandbox.io/s/mz4wjpzy18

Steps to reproduce

  1. click anchored link
  2. scroll back up
  3. click same anchored link => nothing happens

What is expected ?

working anchors accessible from any page (same or different)

What is actually happening?

no navigation is perfomed

This bug report is available on Nuxt community (#c8910)

Additionnal comment

default scrollBehavior does not allow to reach anchors on the same page, but overriding it partially fixes the issue.

@ghost ghost added the cmty:bug-report label Mar 24, 2019
@syffs
Copy link
Author

syffs commented Mar 24, 2019

the workaround I found is to combine to and v-scroll-to:

<nuxt-link :to="{path: '/', hash: 'anchor'}" v-scroll-to="{el: '#anchor'}">link</nuxt-link>

@danielroe
Copy link
Member

danielroe commented Mar 24, 2019

Have you tried hash: '#anchor'?

You can see the default scrollBehavior here and you can override this.

I typically use something like this:

  router: {
    scrollBehavior: async function(to, from, savedPosition) {
      if (savedPosition) {
        return savedPosition;
      }

      const findEl = async (hash, x = 0) => {
        return (
          document.querySelector(hash) ||
          new Promise(resolve => {
            if (x > 50) {
              return resolve(document.querySelector("#app"));
            }
            setTimeout(() => {
              resolve(findEl(hash, ++x || 1));
            }, 100);
          })
        );
      };

      if (to.hash) {
        let el = await findEl(to.hash);
        if ("scrollBehavior" in document.documentElement.style) {
          return window.scrollTo({ top: el.offsetTop, behavior: "smooth" });
        } else {
          return window.scrollTo(0, el.offsetTop);
        }
      }

      return { x: 0, y: 0 };
    }
  },

@syffs
Copy link
Author

syffs commented Mar 24, 2019

@danielroe I did know that it could be overrided, but default scrollBehavior looks fine to me... I'll try to play with this one.

Playing with the repro link, hash: '#anchor' or hash: 'anchor' has the same effect. Only a full refresh of the page actually leads to #anchor

@danielroe
Copy link
Member

Yes, I understand, and agree there's an issue. It looks like hashes work if the page changes (try clicking the link from /about), but not otherwise. I suggest it is to do with the window.$nuxt.$once call.

@usb248
Copy link

usb248 commented Mar 24, 2019

It doesn't work in nuxt 2.4.5 too. On first load, no scroll behavior too.

@syffs
Copy link
Author

syffs commented Mar 24, 2019

@danielroe exactly. clicking on an anchored link, scrolling back up and clicking again: 2nd time doesn't work.

It might be an issue with vue-router though

@chanmathew
Copy link

chanmathew commented Apr 2, 2019

Also running into this issue with 2.5.1, but trying this workaround here for now: https://forum.vuejs.org/t/how-to-handle-anchors-bookmarks-with-vue-router/14563/5 (See 2nd last comment for solution)

@stale
Copy link

stale bot commented Apr 23, 2019

Thanks for your contribution to Nuxt.js!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you would like this issue to remain open:

  1. Verify that you can still reproduce the issue in the latest version of nuxt-edge
  2. Comment the steps to reproduce it

Issues that are labeled as pending will not be automatically marked as stale.

@stale stale bot added the stale label Apr 23, 2019
@stale stale bot closed this as completed Apr 30, 2019
@folamy
Copy link

folamy commented Oct 9, 2019

Nor of the suggested solutions works in latest nuxt version v2.10.0
another thing that gives me concern is that I tried to log document.querySelector() in mounted and it returns null
mounted () { console.log(document.querySelector('#loginView')) }
result: null

@seanohue
Copy link

Any chance of re-opening this issue as it has not been fixed and, based on @folamy 's comment, seems to have gotten worse?

@stale
Copy link

stale bot commented Nov 29, 2019

Thanks for your contribution to Nuxt.js!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you would like this issue to remain open:

  1. Verify that you can still reproduce the issue in the latest version of nuxt-edge
  2. Comment the steps to reproduce it

Issues that are labeled as pending will not be automatically marked as stale.

@stale stale bot added the stale label Nov 29, 2019
@manniL manniL added the pending label Nov 29, 2019
@stale stale bot removed the stale label Nov 29, 2019
@belgacea
Copy link

belgacea commented Feb 29, 2020

Any news on this issue ? Facing it on v2.11.0

@roncarino
Copy link

roncarino commented Mar 1, 2020

Also running into this issue with 2.5.1, but trying this workaround here for now: https://forum.vuejs.org/t/how-to-handle-anchors-bookmarks-with-vue-router/14563/5 (See 2nd last comment for solution)

Hi, I am quite a newbie with Nuxt JS, which is amazing btw.
As @belgacea I am on v2.11.0 and facing this problem. I have used the workaround linked by @chanmathew which I am quoting. Do you have an idea on how to add a "smooth" behaviour to that as well? That solution is ok to me, for the moment, but it does look quite ugly to jump to the anchor in that way, without any fake scrolling.
Thanks for any suggestions/solutions :)

Cheers, Loris

@garyo
Copy link

garyo commented Mar 9, 2020

I'm also interested in seeing a "standard" solution to this.

@rylax
Copy link

rylax commented Mar 18, 2020

Have you tried hash: '#anchor'?

You can see the default scrollBehavior here and you can override this.

I typically use something like this:

  router: {
    scrollBehavior: async function(to, from, savedPosition) {
      if (savedPosition) {
        return savedPosition;
      }

      const findEl = async (hash, x = 0) => {
        return (
          document.querySelector(hash) ||
          new Promise(resolve => {
            if (x > 50) {
              return resolve(document.querySelector("#app"));
            }
            setTimeout(() => {
              resolve(findEl(hash, ++x || 1));
            }, 100);
          })
        );
      };

      if (to.hash) {
        let el = await findEl(to.hash);
        if ("scrollBehavior" in document.documentElement.style) {
          return window.scrollTo({ top: el.offsetTop, behavior: "smooth" });
        } else {
          return window.scrollTo(0, el.offsetTop);
        }
      }

      return { x: 0, y: 0 };
    }
  },

Thank you so much! This worked perfectly for me.

@gaugau3000
Copy link

A workaround can be to use VueScrollTo library.
Please look at rigor789/vue-scrollto#251 issue status before using it (work only as a plugin for now)

@FabianEllenberger
Copy link

@danielroe Thanks, your solution seems to work. But this generates the issue, that nuxt will no longer scroll back to top on each route change automatically, even when using srcollTop: true on every page manually. I'm using Nuxt 2.4.0.

@vadimyen
Copy link

Is there any news on the standard and recommended (not a workaround) solution?

@nuxt nuxt deleted a comment from ashokpokharel977 Aug 20, 2020
@fpolica91
Copy link

fpolica91 commented Oct 20, 2020

Ok I had been struggling with this issue all day today, what I did is inserted the snippet I will leave below in my nuxt.config.js. The following way
` router: {
scrollBehavior: async function(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
}

  const findEl = async (hash, x = 0) => {
    return (
      document.querySelector(hash) ||
      new Promise(resolve => {
        if (x > 50) {
          return resolve(document.querySelector("#app"));
        }
        setTimeout(() => {
          resolve(findEl(hash, ++x || 1));
        }, 100);
      })
    );
  };

  if (to.hash) {
    let el = await findEl(to.hash);
    if ("scrollBehavior" in document.documentElement.style) {
      return window.scrollTo({ top: el.offsetTop, behavior: "smooth" });
    } else {
      return window.scrollTo(0, el.offsetTop);
    }
  }

  return { x: 0, y: 0 };
}

}`

@fkoosan
Copy link

fkoosan commented Nov 18, 2020

Also running into this issue with 2.5.1, but trying this workaround here for now: https://forum.vuejs.org/t/how-to-handle-anchors-bookmarks-with-vue-router/14563/5 (See 2nd last comment for solution)

I have confirmed that the anchor link transitions by the following method with reference to this.
But,
Example
https://localhost:3000/test/#name
However, using mounted did not improve the phenomenon that the anchor link did not transition. I hope it will be supported.

  watch: {
    $route() {
      if (this.$route.hash) {
        setTimeout(() => this.scrollTo(this.$route.hash), 1)
      }
    }
  },
  mounted: function() {
    if (this.$route.hash) {
      this.$router.push({ hash: '' })
    }
  },

  methods: {
    scrollTo: function(hash) {
      setTimeout(() => {
        location.href = hash
      }, 1)
    },

@raym0nd93
Copy link

Been almost 2 years now, any update?

@jonasdumas
Copy link

+1

@danielroe danielroe self-assigned this Mar 5, 2021
Copy link
Member

danielroe commented Mar 5, 2021

Looking at this, it's an upstream issue in vue-router - see vuejs/vue-router#1668 for description, reproduction and some workarounds. Nothing in scrollBehavior will be able to fix this because as far as vue-router is concerned, a route navigation hasn't happened so scrollBehavior is never called.

@m-emre-yalcin
Copy link

image
maybe the main element doesn't overflow and breaking the anchor functionality?

@HenrijsS
Copy link

HenrijsS commented Jul 27, 2021

Workaround for me is just adding a method to the click:

<nuxt-link
  ref="calculator"
  v-bind:to="{ path: '/', hash: '#calculator' }"
  v-on:click.native="scrollToSection('#calculator')"
>
scrollToSection(section) {
  if (this.$nuxt.$route.name === 'index') {
    const navHeight = document.getElementById('navigation').offsetHeight;
    window.scrollTo({
      top: document.querySelector(section).offsetTop - navHeight,
      behavior: 'smooth',
    });
  }
},

Of course you can add this method globally and just pass the section on buttons clicks.

samanthaming added a commit to samanthaming/samanthaming.com that referenced this issue Oct 2, 2021
NuxtLink hash scroll does not scroll back to the top of filter bar
if user manually scrolled to bottom

Related Issue:
nuxt/nuxt#5359

Solution:
Install vue-scrollto package and move scroll to element to outside of
sticky element
@rolexta
Copy link

rolexta commented Oct 31, 2021

got an issue if anchor tag is generated from kind of WYSISWYG editor from the CMS, when click all anchor tag with hash url it makes the page reload again

@HenrijsS
Copy link

@rolexta Make sure that the anchor doesn't include a "/" before the "#"

@fkoosan
Copy link

fkoosan commented Nov 22, 2021

Since then, I have confirmed that it works normally with nuxt v2.15.8 by the following method.
・Url input

http://localhost:3000/#test

・ Anchor in the page

<a href="#test"> move to test </a>

I would appreciate it if you could refer to it.

◆ app / router.scrollBehavior.js

/*
 ** nuxt-link Top Scroll
 */
export default function (to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition
  } else if (to.hash) {
    return {
      selector: to.hash,
    }
  } else {
    return { x: 0, y: 0 }
  }
}

◆ Target page.vue

<template lang="pug">
〜omit〜
  #test TEST
〜omit〜
</template>

  watch: {
    $route() {
      if (this.$route.hash) {
        setTimeout(() => this.scrollTo(this.$route.hash), 1)
      }
    }
  },
  mounted: function() {
    if (this.$route.hash) {
        setTimeout(() => this.scrollTo(this.$route.hash), 1)
    }
  },

  methods: {
    scrollTo: function(hash) {
      setTimeout(() => {
        location.href = hash
      }, 1)
    },

@josh-collinsworth
Copy link

I am running into this issue with Nuxt Bridge, using "nuxt-edge": "latest" and "@nuxt/bridge": "npm:@nuxt/bridge-edge".

No matter what I do, the router never has a value for either hash or query. Even if I explicitly use $router.push, like this:

this.$router.push({ to: '/some-path', hash: '#any' })

It still doesn't work; the hash is just an empty string. Tried with and without the # or a /. Tried using NuxtLink with the entire path as the to attribute; nothing helps. The router just seems to delete the hash and query every time no matter what. (Which means none of the workarounds here is viable in my case, because the hash attribute doesn't exist.)

@danielroe
Copy link
Member

@josh-collinsworth It seems to be working fine for me: https://stackblitz.com/edit/github-n3gkty. Note that if you are using object syntax then you use path and not to.

@adamchipperfield
Copy link

Is there a way we can get this working without hard coded solutions? I have an app where we're passing whatever link is defined in the CMS to nuxt-link.

@Lucsy3012
Copy link

Still no updates on this without using workarounds? I'm no leaning towards just using an <a> with href="#anchor" instead. The smooth scrolling effect can also be achieved by adding this to the CSS.

html {
    scroll-behavior: smooth;
}

@ryanklarhoelter
Copy link

I think that might be fixed by this PR:

vuejs/vue-router#3592

Isn't it?

@ankitsinghaniyaz
Copy link

Waiting for this to be sorted out 😅

@bexter89
Copy link

saaame 👀

@bayasdev
Copy link

Is this ever going to be fixed? 🤔

@rchl
Copy link

rchl commented Mar 25, 2023

Appears to be working fine now, after vue-router bug was fixed. I've taken the initial codesanbox example, exported it, updated Nuxt to 2.16.3, ran yarn upgrade and it worked as expected.

@manniL
Copy link
Member

manniL commented Mar 26, 2023

Closing here then 👍🏻

@manniL manniL closed this as not planned Won't fix, can't repro, duplicate, stale Mar 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests