N
Nuxt19h ago
Yaiko

Exclude page from nested layout

Environment - Node Version: v20.19.5 - Nuxt Version: 4.2.1 - CLI Version: 3.30.0 - Nitro Version: 2.12.9 - Package Manager: bun@1.3.4 Reproduction - Describe the bug I have a Nested layout pages/[category].tsx and I want to exclude pages/[category]/posts/index.tsx from that nested layout and use another layout while preserving the NuxtPage with keepalive if the user changes back the the nested layout again. Is possible?, for now I only could make a rendering condition from the Nested layout to not render the layout and only the default slot but I don't know if thats the right solution. Thanks. Additional context No response Logs




7 Replies
kapa.ai
kapa.ai19h ago
Hi @Yaiko. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- It’s currently unclear from the provided sources whether Nuxt 3/4 supports fully excluding a single child route from a nested route wrapper while still keeping page-level <KeepAlive> state intact. The linked GitHub issue you quoted was closed without a documented solution or reproduction, so there is no official pattern described there. [Exclude page issue] From the available information, there are two related building blocks you can rely on, but not a fully documented recipe for your exact case: 1. Nested route “pseudo layouts” with @layout.vue Nuxt supports a pages/parent/@layout.vue convention that acts as the wrapper for all children under parent. [Nested layouts] Example:
pages/
├─ [category]/
│ ├─ @layout.vue // wrapper for all [category] children
│ ├─ index.vue
│ └─ posts/
│ └─ index.vue

pages/
├─ [category]/
│ ├─ @layout.vue // wrapper for all [category] children
│ ├─ index.vue
│ └─ posts/
│ └─ index.vue

@layout.vue should contain <NuxtPage /> to render its child routes. This gives you a nested “layout” per category, but the sources do not show a built‑in way to declare “use a different layout for this specific child, skipping @layout.vue.” [Nested layouts] 2. KeepAlive behavior for pages and layouts Nuxt has specific fixes to preserve page <KeepAlive> across layout changes and to avoid cache resets when using keepalive on <NuxtPage>. [Keepalive fix; Preserve across layouts] Example usage shown:
<script setup lang="ts">
const exclude = ['cpage', 'dpage']
</script>

<template>
<NuxtLayout>
<NuxtPage :keepalive="{ exclude }" />
</NuxtLayout>
</template>

<script setup lang="ts">
const exclude = ['cpage', 'dpage']
</script>

<template>
<NuxtLayout>
<NuxtPage :keepalive="{ exclude }" />
</NuxtLayout>
</template>

These PRs ensure: - NuxtPage’s keepalive doesn’t constantly reset its cache. - Cached pages can survive layout switches when NuxtLayout is wrapped in <KeepAlive>. [Keepalive fix; Preserve across layouts] However, none of the provided sources show: - A way for a child route (e.g. [category]/posts/index) to declare “do not use the parent @layout.vue route wrapper at all,” nor - A concrete example of combining that with keepalive so that when you return to another [category] child, its state is restored. Because of that, I can’t confidently describe an officially recommended pattern for “exclude one child page from a nested layout but still keep [category] pages alive” beyond the workaround you already mentioned (conditionally rendering only the slot content in the nested layout). [Exclude page issue] Given the current information: - Using a nested wrapper via @layout.vue plus conditional rendering of its chrome (header/sidebar/etc.) based on the current route is the only approach explicitly hinted at in your issue. [Exclude page issue; Nested layouts] - keepalive handling itself is supported and should work across layout changes, but how it interacts with “skipping” a nested wrapper for just one child route isn’t documented in these sources. [Keepalive fix; Preserve across layouts] So: - Is it possible? The knowledge sources do not explicitly confirm that your exact scenario is supported or how to implement it. - Is your current conditional-rendering workaround “wrong”? The sources do not provide a better, documented alternative; they do not say this pattern is incorrect. For a definitive answer or pattern, the Nuxt team in the linked issue asked for a minimal reproduction and suggested using Discussions. [Exclude page issue] Creating such a repro and asking in Discussions is, based on the available information, the next recommended step. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai19h ago
<@176572993563131904> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Cake
Cake18h ago
@Yaikowhat do you mean exclude it form the layout? also a minimal reproduction would be helpful
Shay Rosenfeld
Shay Rosenfeld18h ago
did you try this?
<script setup lang="ts">
definePageMeta({
layout: false,
})
</script>

<template>
<div>
<NuxtLayout name="custom">
<template #header>
Some header template content.
</template>

The rest of the page
</NuxtLayout>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: false,
})
</script>

<template>
<div>
<NuxtLayout name="custom">
<template #header>
Some header template content.
</template>

The rest of the page
</NuxtLayout>
</div>
</template>
https://nuxt.com/docs/4.x/directory-structure/app/layouts#overriding-a-layout-on-a-per-page-basis If I understand you correctly you just want to give a specific page a different layout, right?
Yaiko
YaikoOP14h ago
I have this layouts: layouts/default.vue layouts/category.vue layouts/post.vue Then I have all the routes in pages/[category]/... using layout default + layout category (it works well): pages/[category].vue (So is nested) <script setup lang="ts"> definePageMeta({ layout: 'default', // Using default layout }) </script> <template> <div> <NuxtLayout name="category"> // Nested layout <NuxtPage keepalive /> </NuxtLayout> </div> </template> But I have a specific route pages/[category]/posts/index.vue where I just want to use the layout "post" excluding the layout "category" for this route and keep (if possible) the keepalive of the NuxtPage. @Cake @Shay Rosenfeld
Cake
Cake9h ago
you can try adding a route meta in posts page for like excludeCategoryLayout: true, then in [category].vue you'd do something like:
<script setup lang="ts">
definePageMeta({
layout: 'default', // Using default layout
})
const route = useRoute()
const layout = computed(() => {
return route.meta.excludeCategoryLayout ? false : 'category'
})
</script>

<template>
<div>
<NuxtLayout :name="layout"> // Nested layout
<NuxtPage keepalive />
</NuxtLayout>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: 'default', // Using default layout
})
const route = useRoute()
const layout = computed(() => {
return route.meta.excludeCategoryLayout ? false : 'category'
})
</script>

<template>
<div>
<NuxtLayout :name="layout"> // Nested layout
<NuxtPage keepalive />
</NuxtLayout>
</div>
</template>
@Yaiko not sure if keepalive will work tho
Yaiko
YaikoOP7h ago
Thanks! that worked.

Did you find this page helpful?