What Causes This Error?
This warning appears when you reference a layout in your page that doesn’t exist in the layouts/ directory.
Common Causes and Fixes
Cause 1: Layout File Doesn’t Exist
// In your page
definePageMeta({
layout: 'admin' // But layouts/admin.vue doesn't exist!
})
Fix: Create the layout file:
<!-- layouts/admin.vue -->
<template>
<div>
<AdminSidebar />
<main>
<slot />
</main>
</div>
</template>
Cause 2: Typo in Layout Name
// ❌ Wrong - typo
definePageMeta({
layout: 'defualt' // Should be 'default'
})
// ✅ Correct
definePageMeta({
layout: 'default'
})
Cause 3: Case Sensitivity
Layout names are derived from filenames and are case-sensitive:
// If your file is: layouts/AdminPanel.vue
// ❌ Wrong
definePageMeta({
layout: 'adminpanel'
})
// ✅ Correct
definePageMeta({
layout: 'AdminPanel'
})
Cause 4: Wrong Directory
Layouts must be in the layouts/ directory at the project root:
// ❌ Wrong locations
components/layouts/default.vue
pages/layouts/default.vue
// ✅ Correct location
layouts/default.vue
Cause 5: Dynamic Layout with Invalid Value
// ❌ Wrong - layout might be undefined or invalid
const layout = computed(() => user.value?.role)
definePageMeta({
layout: layout // Could be undefined!
})
// ✅ Correct - provide fallback
definePageMeta({
layout: computed(() => user.value?.isAdmin ? 'admin' : 'default')
})
Creating Layouts
Basic Layout
<!-- layouts/default.vue -->
<template>
<div>
<Header />
<slot />
<Footer />
</div>
</template>
Custom Layout
<!-- layouts/blog.vue -->
<template>
<div class="blog-layout">
<BlogHeader />
<aside>
<BlogSidebar />
</aside>
<main>
<slot />
</main>
</div>
</template>
Using Layouts
Static Layout Assignment
// pages/admin/index.vue
definePageMeta({
layout: 'admin'
})
Dynamic Layout
<script setup>
const route = useRoute()
definePageMeta({
layout: false // Disable layout initially
})
// Set layout dynamically
const layout = computed(() => {
return route.meta.isAdmin ? 'admin' : 'default'
})
</script>
<template>
<NuxtLayout :name="layout">
<NuxtPage />
</NuxtLayout>
</template>
Disabling Layout
definePageMeta({
layout: false // No layout for this page
})
Using setPageLayout
You can change layouts programmatically:
// Change layout at runtime
setPageLayout('admin')
Warning: Don’t call setPageLayout on the server or during hydration—it will cause errors.
Debugging
List available layouts:
# Check your layouts directory
ls -la layouts/
Or in your code:
// In nuxt.config.ts, add this to see registered layouts
export default defineNuxtConfig({
hooks: {
'pages:extend'(pages) {
console.log('Layouts:', pages)
}
}
})
Layout Naming Convention
| File Name | Layout Name |
|---|---|
default.vue | default |
admin.vue | admin |
blog-post.vue | blog-post |
AdminPanel.vue | AdminPanel |
Quick Checklist
- Layout file exists in
layouts/directory - File has
.vueextension - Layout name matches filename exactly (case-sensitive)
- No typos in layout name
- Dynamic layout always resolves to valid value
- Layout file has
<slot />for page content