nuxt icon indicating copy to clipboard operation
nuxt copied to clipboard

`useRoute.matched` is not returning all matching routes

Open Aietes opened this issue 1 year ago • 4 comments

Environment

  • Operating System: Linux
  • Node Version: v18.20.3
  • Nuxt Version: 3.13.0
  • CLI Version: 3.13.0
  • Nitro Version: 2.9.7
  • Package Manager: [email protected]
  • Builder: -
  • User Config: compatibilityDate, future, devtools
  • Runtime Modules: -
  • Build Modules: -

Reproduction

https://stackblitz.com/edit/github-ezruhh?file=app%2Fapp.vue

Describe the bug

With future: { compatibilityVersion: 4:} set in nuxt.config.ts, useRouter.matched is returning only 1 item on dynamic routes, e.g. /app/pages/[id].vue. This is unexpected behavior, as $route.matched should be an array of normalized matched routes with current route location, in this case it should contain two items. This bug breaks components depending on this property, e.g. NuxtLink activeClass stops working for dynamic routes.

Additional context

No response

Logs

No response

Aietes avatar Aug 26 '24 14:08 Aietes

This doesn't seem to be related to future.compatibilityVersion. Did you have a version of Nuxt + vue-router that behaves as you expect?

updated repro to show same behaviour on previous version of nuxt/vue-router:

https://stackblitz.com/edit/github-ezruhh-g2prlc

danielroe avatar Aug 27 '24 09:08 danielroe

It worked before we changed to future, but as your repro shows, it doesn't seem to be the root cause. We noticed NuxtLink is not working as expected, as activeClass is not triggered on dynamic subroutes like it used to.

Aietes avatar Aug 27 '24 12:08 Aietes

We found out why it worked before, it had nothing to do with versions. We had an additional page1.vue in pages, which rendered the index.vue as NuxtPage, something like this:

-| pages/
---| page1/
------| [id].vue
------| index.vue
---| page1.vue

page1.vue

<template>
  <NuxtPage />
</template>

With that, $route.matched contains two objects, and NuxtLink works. It's an accidental workaround. However, this is still a bug, as actually there should be 3 matches when looking at the routes:

image

I'm not sure why this happens, as in general an index.vue in another folder matches as expected, e.g.:

-| pages/
---| page1/
------| [id].vue
------| index.vue
---| page3/
------| index.vue

has one matched route for page3, but also only one matched route for /page1/id, missing page1 as a match.

https://stackblitz.com/edit/github-ezruhh-yr5ch7?file=components%2Fsidebar.vue

Aietes avatar Aug 27 '24 13:08 Aietes

I encountered the same issue

atonemi avatar Sep 11 '24 15:09 atonemi

Is there any update on this? It's still in triage, I think this should be confirmed as a bug?

Aietes avatar Oct 25 '24 12:10 Aietes

Same problem here. I have some URLs matching with the wrong route and then if I return false on the validation function it won't search for more matches since the route.matches has only the current one.

andreclemente avatar Nov 12 '24 15:11 andreclemente

Here's my workaround, simulating what nuxt 2 was doing:

hooks: {
    'pages:extend' (routes) {
      const routeNameSplitter = '/'
      const root = createResolver(import.meta.url).resolve('./pages')

      function updateName (rRoutes) {
        if (!rRoutes) return

        // eslint-disable-next-line no-restricted-syntax
        for (const route of rRoutes) {
          const aux = route.file.substring(root.length + 1).match(/\(.*?\)/g)
          const relativePath = route.file.substring(root.length + 1).replace(/\(.*?\)/g, '')
          route.name = relativePath.slice(0, -4)
            .replace(/\/index$/, '')
            .replace(/\//g, routeNameSplitter)
            .replace(/\[\.\.\.all\]/g, 'all')
            .replace(/\[(.+?)\]/g, '$1')

          
          // WORKAROUND
          if (aux) {
            aux.forEach(validParams => {
              route.path = route.path
                .replace(/\(\)/, validParams)
            });
          }
         // END WORKAROUND

          updateName(route.children)
        }
      }
      updateName(routes)
    }
  }
}

andreclemente avatar Nov 12 '24 15:11 andreclemente