Setting the file. One moment.
Subchapter 4.2
references/advanced-layers.mdMarkdown5 KBView on GitHub
Layers allow sharing and reusing partial Nuxt applications across projects. They can include components, composables, pages, layouts, and configuration.
// nuxt.config.ts
export default defineNuxtConfig({
extends: [
'@my-org/base-layer',
'@nuxtjs/ui-layer',
],
})// nuxt.config.ts
export default defineNuxtConfig({
extends: [
'github:username/repo',
'github:username/repo/base', // Subdirectory
'github:username/repo#v1.0', // Specific tag
'github:username/repo#dev', // Branch
'gitlab:username/repo',
'bitbucket:username/repo',
],
})// nuxt.config.ts
export default defineNuxtConfig({
extends: [
'../base-layer',
'./layers/shared',
],
})Place in layers/ directory for automatic discovery:
my-app/
├── layers/
│ ├── base/
│ │ └── nuxt.config.ts
│ └── ui/
│ └── nuxt.config.ts
└── nuxt.config.tsMinimal layer structure:
my-layer/
├── nuxt.config.ts # Required
├── app/
│ ├── components/ # Auto-merged
│ ├── composables/ # Auto-merged
│ ├── layouts/ # Auto-merged
│ ├── middleware/ # Auto-merged
│ ├── pages/ # Auto-merged
│ ├── plugins/ # Auto-merged
│ └── app.config.ts # Merged
├── server/ # Auto-merged
└── package.json// my-layer/nuxt.config.ts
export default defineNuxtConfig({
// Layer configuration
app: {
head: {
title: 'My Layer App',
},
},
// Shared modules
modules: ['@nuxt/ui'],
})<!-- my-layer/app/components/BaseButton.vue -->
<template>
<button class="base-btn">
<slot />
</button>
</template>Use in consuming project:
<template>
<BaseButton>Click me</BaseButton>
</template>// my-layer/app/composables/useTheme.ts
export function useTheme() {
const isDark = useState('theme-dark', () => false)
const toggle = () => isDark.value = !isDark.value
return { isDark, toggle }
}Override order (highest to lowest):
extends array (first > last)Control order with prefixes:
layers/
├── 1.base/ # Lower priority
└── 2.theme/ # Higher priorityAccess layer files:
// Auto-scanned layers get aliases
import Component from '#layers/base/components/Component.vue'Named aliases:
// my-layer/nuxt.config.ts
export default defineNuxtConfig({
$meta: {
name: 'my-layer',
},
})// In consuming project
import { something } from '#layers/my-layer/utils'{
"name": "my-nuxt-layer",
"version": "1.0.0",
"type": "module",
"main": "./nuxt.config.ts",
"dependencies": {
"@nuxt/ui": "^2.0.0"
},
"devDependencies": {
"nuxt": "^3.0.0"
}
}For private git repos:
export GIGET_AUTH=<github-token>// my-layer/nuxt.config.ts
import { fileURLToPath } from 'node:url'
import { dirname, join } from 'node:path'
const currentDir = dirname(fileURLToPath(import.meta.url))
export default defineNuxtConfig({
css: [
join(currentDir, './assets/main.css'),
],
})// nuxt.config.ts
export default defineNuxtConfig({
extends: [
['github:user/layer', { install: true }],
],
})// nuxt.config.ts
export default defineNuxtConfig({
extends: ['./base-layer'],
// Disable modules from layer
image: false, // Disables @nuxt/image
pinia: false, // Disables @pinia/nuxt
})Create a new layer:
npx nuxi init --template layer my-layertheme-layer/
├── nuxt.config.ts
├── app/
│ ├── app.config.ts
│ ├── components/
│ │ ├── ThemeButton.vue
│ │ └── ThemeCard.vue
│ ├── composables/
│ │ └── useTheme.ts
│ └── assets/
│ └── theme.css
└── package.json// theme-layer/nuxt.config.ts
export default defineNuxtConfig({
css: ['~/assets/theme.css'],
})// theme-layer/app/app.config.ts
export default defineAppConfig({
theme: {
primaryColor: '#00dc82',
darkMode: false,
},
})// consuming-app/nuxt.config.ts
export default defineNuxtConfig({
extends: ['theme-layer'],
})
// consuming-app/app/app.config.ts
export default defineAppConfig({
theme: {
primaryColor: '#ff0000', // Override
},
})