What Causes This Warning?
This warning appears when you have a layouts/ directory with layout files, but your app.vue (or entry point) doesn’t include the <NuxtLayout> component to render them.
The Problem
layouts/
default.vue ← Layout exists
admin.vue ← Layout exists
app.vue ← But NuxtLayout isn't used
<!-- app.vue -->
<template>
<!-- ❌ Missing NuxtLayout - layouts won't render -->
<NuxtPage />
</template>
The Fix
Add NuxtLayout to app.vue
<!-- app.vue -->
<template>
<!-- ✅ Wrap NuxtPage with NuxtLayout -->
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
Understanding the Layout System
Basic Setup
my-nuxt-app/
├── layouts/
│ └── default.vue ← Applied automatically
├── pages/
│ └── index.vue
└── app.vue ← Must include NuxtLayout
<!-- layouts/default.vue -->
<template>
<div>
<Header />
<main>
<slot /> <!-- Page content goes here -->
</main>
<Footer />
</div>
</template>
<!-- app.vue -->
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
Multiple Layouts
<!-- layouts/default.vue -->
<template>
<div class="default-layout">
<Navbar />
<slot />
<Footer />
</div>
</template>
<!-- layouts/admin.vue -->
<template>
<div class="admin-layout">
<AdminSidebar />
<div class="admin-content">
<slot />
</div>
</div>
</template>
<!-- layouts/blank.vue -->
<template>
<div class="blank-layout">
<slot />
</div>
</template>
Using Layouts in Pages
<!-- pages/index.vue - uses default layout -->
<template>
<div>Home page content</div>
</template>
<!-- pages/admin/index.vue - uses admin layout -->
<script setup>
definePageMeta({
layout: 'admin'
})
</script>
<template>
<div>Admin dashboard</div>
</template>
<!-- pages/login.vue - uses blank layout -->
<script setup>
definePageMeta({
layout: 'blank'
})
</script>
<template>
<div>Login form</div>
</template>
Alternative: No app.vue
If you don’t have an app.vue, Nuxt creates a default one. But if you create app.vue, you must include NuxtLayout:
<!-- Without app.vue - Nuxt handles it automatically -->
<!-- With app.vue - you must add NuxtLayout yourself -->
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
Disabling Layouts
If you don’t want layouts at all:
Option 1: Remove the layouts directory
rm -rf layouts/
Option 2: Disable for specific pages
<script setup>
definePageMeta({
layout: false // Disables layout for this page
})
</script>
Option 3: Keep app.vue without NuxtLayout
If you explicitly don’t want layout functionality:
<!-- app.vue -->
<template>
<!-- No NuxtLayout - intentionally not using layouts -->
<NuxtPage />
</template>
But then remove the layouts/ directory to avoid the warning.
Layout with Transitions
<!-- app.vue -->
<template>
<NuxtLayout>
<NuxtPage :transition="{ name: 'page', mode: 'out-in' }" />
</NuxtLayout>
</template>
<style>
.page-enter-active,
.page-leave-active {
transition: opacity 0.3s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
}
</style>
Dynamic Layout Switching
<!-- app.vue -->
<script setup>
const route = useRoute()
const layout = computed(() => route.meta.layout || 'default')
</script>
<template>
<NuxtLayout :name="layout">
<NuxtPage />
</NuxtLayout>
</template>
Layout with Error Handling
<!-- app.vue -->
<template>
<NuxtLayout>
<NuxtErrorBoundary>
<NuxtPage />
<template #error="{ error, clearError }">
<ErrorPage :error="error" @clear="clearError" />
</template>
</NuxtErrorBoundary>
</NuxtLayout>
</template>
Named Slots in Layouts
<!-- layouts/with-sidebar.vue -->
<template>
<div class="layout">
<aside>
<slot name="sidebar">Default sidebar</slot>
</aside>
<main>
<slot /> <!-- Default slot for page content -->
</main>
</div>
</template>
Usage in page:
<!-- pages/products.vue -->
<script setup>
definePageMeta({
layout: 'with-sidebar'
})
</script>
<template>
<div>
<template #sidebar>
<ProductFilters />
</template>
<!-- Main content goes in default slot -->
<ProductList />
</div>
</template>
Checking Current Layout
<script setup>
const layout = useLayout()
console.log('Current layout:', layout.value)
// Change layout programmatically
setPageLayout('admin')
</script>
Quick Checklist
-
app.vueincludes<NuxtLayout>wrapping<NuxtPage> - Layout files are in
layouts/directory - Layout files use
<slot />for page content - Pages specify layout with
definePageMeta({ layout: 'name' }) - If not using layouts, remove
layouts/directory