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?
No description
25 Replies
kapa.ai
kapa.ai5mo ago
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:
pages/
[gameId].vue
[gameId]/
overview.vue
versions.vue
version/
[version]/
index.vue
pages/
[gameId].vue
[gameId]/
overview.vue
versions.vue
version/
[version]/
index.vue
If you rename 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: ----------------------
kapa.ai
kapa.ai5mo ago
<@193115930857832448> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Cake
Cake5mo ago
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
Bobakanoosh
BobakanooshOP5mo ago
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
Cake
Cake5mo ago
where is the "parent layout" defined?
Bobakanoosh
BobakanooshOP5mo ago
[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
No description
Cake
Cake5mo ago
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/foo
Bobakanoosh
BobakanooshOP5mo ago
No 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 it
Cake
Cake5mo ago
you need it for proper nesting logic
Bobakanoosh
BobakanooshOP5mo ago
Sure yeah i guess for the routes, I guess I just meant the shareable js/html thast within the file
Cake
Cake5mo ago
you can still have a GameLayout layout and use NuxtLayout and NuxtPage in [gameId].vue
Bobakanoosh
BobakanooshOP5mo ago
Are you referring to a nuxt layout when you say layout
Cake
Cake5mo ago
and in [gameId]/versions.vue, have layout: false
Bobakanoosh
BobakanooshOP5mo ago
ahhh hmm
Cake
Cake5mo ago
yes your routes are nested, so I don't recommend working your way in way which makes them not propely nested
Bobakanoosh
BobakanooshOP5mo ago
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 nested
Wdym I'll give it a try using an actual nuxt layout - right now I just have two (unauthed vs authed)
Cake
Cake5mo ago
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 layout
Bobakanoosh
BobakanooshOP5mo ago
Does 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.
Cake
Cake5mo ago
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 it
Bobakanoosh
BobakanooshOP5mo ago
ahhhh beautiful yeah that was the toher thing about layouts that irked me not being able to do definePageMeta({layout: ...}) in the [gameId]
Cake
Cake5mo ago
you can
Bobakanoosh
BobakanooshOP5mo ago
🧢
Cake
Cake5mo ago
[gameId].vue
Bobakanoosh
BobakanooshOP5mo ago
i swear it hasnt worked lol
Cake
Cake5mo ago
but you don't want it there. in [gameId].vue, you use NuxtLayout, the component
<NuxtLayout name="gameLayout">
<NuxtPage />
</NuxtLayout>
<NuxtLayout name="gameLayout">
<NuxtPage />
</NuxtLayout>
in [gameId]/versions.vue you use definePageMeta to disable layout (gameLayout) with layout: false

Did you find this page helpful?