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

URL fragment (hash anchor) lost when global guard fills in .html suffix #3142

Open
1 task done
calin-darie opened this issue May 21, 2023 · 1 comment
Open
1 task done

Comments

@calin-darie
Copy link

calin-darie commented May 21, 2023

  • I confirm that this is an issue rather than a question.

Bug report

Steps to reproduce

  1. Create a vuepress site. This issue should be reproducible with the default theme and settings
  2. Create an .md page with heading titles. The issue is much clearer when smooth scrolling is off (so when combined with Scroll to anchor doesn't work under Chrome when smooth scrolling is disabled #2558 ), and with the target header is off-screen (if you need to scroll down to reach it).
  3. Instead of mypage.html#mytitle, navigate to mypage#mytitle by following external links or by pasting the URL in the browser
    Examples:

What is expected?

  1. The fragment hash is not lost
  2. The page scrolls down automatically to the desired spot.

What is actually happening?

Any URL fragment hash and query string are erased by this router guard: https://github.com/vuejs/vuepress/blob/38e98634af117f83b6a32c8ff42488d91b66f663/packages/%40vuepress/core/lib/client/redirect.js

Other relevant information

The fix is to patch the router object, instead of passing on just the path. Let me know if you'd approve a pull request:

        if (isRouteExists(router, endingHtmlUrl)) {
          next({
            ...to,
            path: endingHtmlUrl
          })
        } else if (isRouteExists(router, endingSlashUrl)) {
          next({
            ...to,
            path: endingSlashUrl
          })
        } else {
          next()
        }
      } else if (/\/$/.test(to.path)) {
        const endingHtmlUrl = to.path.replace(/\/$/, '') + '.html'
        if (isRouteExists(router, endingHtmlUrl)) {
          next({
            ...to,
            path: endingHtmlUrl
          })
  • Output of npx vuepress info in my VuePress project:
    As mentioned above, it reproduces with the official vuepress docs, so this is not particularly relevant.
@calin-darie
Copy link
Author

Dirty hack. Until this gets fixed in the official version, I've patched the router global hooks:

export default ({
  Vue, // the version of Vue being used in the VuePress app
  options, // the options for the root Vue instance
  router, // the router instance for the app
  siteData // site metadata
}) => {
  // ...apply enhancements for the site.
  router.beforeHooks =[];
  router.beforeEach((to, from, next) => { // fixed version

Please let's fix vuepress v1 and let me delete this abomination.

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

No branches or pull requests

1 participant