vuejs / router

🚦 The official router for Vue.js

Home Page:https://router.vuejs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

createMemoryHistory and createWebHistory differs with base

yooouuri opened this issue · comments

Reproduction

https://github.com/yooouuri/vue-router-problem

Steps to reproduce the bug

The createCurrentLocation in createWebHistory https://github.com/vuejs/router/blob/main/packages/router/src/history/html5.ts#L38-L56 creates the current location from window.location.

Without a base set, https://localhost:5173/be/marktplaats will result in be/marktplaats. With /be/ as base, the result is /marktplaats.

(I removed the ts stuff)

function stripBase(pathname, base) {
  // no base or base is not found at the beginning
  if (!base || !pathname.toLowerCase().startsWith(base.toLowerCase()))
    return pathname
  return pathname.slice(base.length) || '/'
}

function createCurrentLocation(base, location) {
  const { pathname, search, hash } = location
  // allows hash bases like #, /#, #/, #!, #!/, /#!/, or even /folder#end
  const hashPos = base.indexOf('#')
  if (hashPos > -1) {
    let slicePos = hash.includes(base.slice(hashPos))
      ? base.slice(hashPos).length
      : 1
    let pathFromHash = hash.slice(slicePos)
    // prepend the starting slash to hash so the url starts with /#
    if (pathFromHash[0] !== '/') pathFromHash = '/' + pathFromHash
    return stripBase(pathFromHash, '')
  }

  const path = stripBase(pathname, base)

  return path + search + hash
}
image image

When I create a router with createMemoryHistory('/be/' (in SSR), and I do a router push with the URL and wait for it:

await router.push('/be/marktplaats')
await router.isReady()

The result from router.currentRoute.value is (SSR):

{
  fullPath: '/be/marktplaats',
  path: '/be/marktplaats',
  query: {},
  hash: '',
  name: 'not-found___nl',
  params: { pathMatch: [ 'be', 'marktplaats' ] },
  matched: [
    {
      path: '/:pathMatch(.*)*',
      redirect: undefined,
      name: 'not-found___nl',
      meta: {},
      aliasOf: undefined,
      beforeEnter: undefined,
      props: [Object],
      children: [],
      instances: {},
      leaveGuards: Set(0) {},
      updateGuards: Set(0) {},
      enterCallbacks: {},
      components: [Object]
    }
  ],
  meta: {},
  redirectedFrom: undefined,
  href: '/be/be/marktplaats'
}

Expected behavior

The view is matched both SSR and client side.

Actual behavior

The result in SSR and client side for router.currentRoute.value is different with same base path in createMemoryHistory and createWebHistory

The route is not matched in SSR, but in client side it is.

Additional information

No response

When defining a base, it's not passed to any of the router.push() functions. I think you can check the Nuxt code base if you want to see how the implement the router, it should be helpful to you