Same path nested routes question
I have the routing setup as screenshotted below.
[gameId].vue is a layout that contains 2 tabs: overview.vue and versions.vue.
The versions page has links to individual versions, which are in the version/[version]/index.vue route.
Ideally I'd like that route to be versions instead of version, so that it matches the tab before it.
But if I do that, it treats it as a nested layout.
How can I fix this?
25 Replies
Hi @Bobakanoosh. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
In Nuxt, when you have a directory structure like this:
If you rename
This avoids the collision, but the URL will be
For example, you could use a route like
If you really need
The behavior you’re seeing is a result of Nuxt’s file-based routing system, which treats a file and a directory of the same name as a parent-child (layout-nested) relationship. To avoid this, you must either accept a different URL structure or use custom routing to override the default behavior. There is no built-in way to have both
version/ to versions/ (so it matches the tab name), Nuxt will treat pages/[gameId]/versions.vue as the route for /[gameId]/versions and pages/[gameId]/versions/[version]/index.vue as a nested route under /[gameId]/versions. This means that navigating to /[gameId]/versions/[version] will render the versions.vue page as a layout, with the [version]/index.vue as its child, displayed via <NuxtPage /> in versions.vue.
This is the expected behavior in Nuxt's file-based routing: a directory and a file with the same name at the same level will result in the file acting as the parent layout for the nested routes in the directory. If you want /[gameId]/versions to be a page and /[gameId]/versions/[version] to be a sibling route (not nested under the versions.vue layout), you need to avoid this directory/file name collision.
Workarounds:
1. Keep the directory as version/This avoids the collision, but the URL will be
/[gameId]/version/[version] instead of /[gameId]/versions/[version].
2. Use a different structure for the detail page:For example, you could use a route like
/[gameId]/versions-version/[version] or /[gameId]/versions_detail/[version] to avoid the collision, but this changes your URL.
3. Custom Routing:If you really need
/[gameId]/versions and /[gameId]/versions/[version] as separate, non-nested routes, you can use custom routing with router options to manually define the routes, but this is more advanced and you lose some of the benefits of file-based routing.
Summary:The behavior you’re seeing is a result of Nuxt’s file-based routing system, which treats a file and a directory of the same name as a parent-child (layout-nested) relationship. To avoid this, you must either accept a different URL structure or use custom routing to override the default behavior. There is no built-in way to have both
/[gameId]/versions as a page and /[gameId]/versions/[version] as a non-nested sibling route using only file-based routing.
For more details, see the Nuxt documentation on nested routes and dynamic routes.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@193115930857832448> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
remove your
versions.vue page
tho I don't understand why you don't want them nested, what you described is nested routes
The versions page has links to individual versions
Yes its a nested route but I dont want it to share the same layout as the parent.
Versions.vue contains a table of items, and clicking into one of those items brings you to view the individual Version.
I still need versions.vue though for the tab
where is the "parent layout" defined?
[gameId].vue I suppose. This is a "game" page that has a header (info about the game) and then 3 tabs (overview, versions, dumper config).
But once you're within the "version" page I dont want to show the "game" page header
you can move the header outside of
[gameId].vue then
for example, [gameId]/index.vue then the header will only show on /games/123
and won't in /games/123/fooNo point in
[gameId] at all at that poine then really, might as well just make a component like GameLayout and manually use that in overview.vue, versions.vue, etc
since [gameId] has a NuxtPage in ityou need it for proper nesting logic
Sure yeah i guess for the routes, I guess I just meant the shareable js/html thast within the file
you can still have a
GameLayout layout
and use NuxtLayout and NuxtPage in [gameId].vueAre you referring to a nuxt layout when you say layout
and in
[gameId]/versions.vue, have layout: falseahhh hmm
yes
your routes are nested, so I don't recommend working your way in way which makes them not propely nested
Whenever I first started using Nuxt, I had issues with layouts not behaving how I expected so I've stayed away from them and have mostly used these "layouts" where you have the file ([gameid].vue) match the folder
working your way in way which makes them not propely nestedWdym I'll give it a try using an actual nuxt layout - right now I just have two (unauthed vs authed)
like removing
[gameId].vue
or versions.vue
and where you want the GameLayout to be used, u'd manually use layout: "GameLayout", for example in [gameId]/index.vue
otherwise it would look for the default.vue layoutDoes it support nested layouts though? I dont see anything in docs mentioning it.
I would want default.vue and GameLayout showing
Nuxt
layouts · Nuxt Directory Structure v3
Nuxt provides a layouts framework to extract common UI patterns into reusable layouts.
yes
other option is directly doing
<NuxtLayout name="gameLayout" in [gameId].vue
then u don't have to manually do layout: "GameLayout" in children of [gameId]
that would be the default, and you'd only do layout: false in the children routes where you don't want itahhhh beautiful yeah that was the toher thing about layouts that irked me
not being able to do
definePageMeta({layout: ...}) in the [gameId]you can
🧢
[gameId].vuei swear it hasnt worked lol
but you don't want it there.
in
[gameId].vue, you use NuxtLayout, the component
in [gameId]/versions.vue you use definePageMeta to disable layout (gameLayout) with layout: false