@plutocms/supabase 0.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/nuxt/GENERATION.md +5 -0
- package/.agents/skills/nuxt/SKILL.md +55 -0
- package/.agents/skills/nuxt/references/advanced-hooks.md +289 -0
- package/.agents/skills/nuxt/references/advanced-layers.md +299 -0
- package/.agents/skills/nuxt/references/advanced-module-authoring.md +554 -0
- package/.agents/skills/nuxt/references/best-practices-data-fetching.md +357 -0
- package/.agents/skills/nuxt/references/best-practices-ssr.md +355 -0
- package/.agents/skills/nuxt/references/core-cli.md +263 -0
- package/.agents/skills/nuxt/references/core-config.md +162 -0
- package/.agents/skills/nuxt/references/core-data-fetching.md +236 -0
- package/.agents/skills/nuxt/references/core-deployment.md +224 -0
- package/.agents/skills/nuxt/references/core-directory-structure.md +269 -0
- package/.agents/skills/nuxt/references/core-modules.md +292 -0
- package/.agents/skills/nuxt/references/core-routing.md +226 -0
- package/.agents/skills/nuxt/references/features-components-autoimport.md +328 -0
- package/.agents/skills/nuxt/references/features-components.md +264 -0
- package/.agents/skills/nuxt/references/features-composables.md +276 -0
- package/.agents/skills/nuxt/references/features-server.md +265 -0
- package/.agents/skills/nuxt/references/features-state.md +194 -0
- package/.agents/skills/nuxt/references/rendering-modes.md +237 -0
- package/.agents/skills/nuxt-ui/SKILL.md +334 -0
- package/.agents/skills/nuxt-ui/references/components.md +377 -0
- package/.agents/skills/nuxt-ui/references/composables.md +127 -0
- package/.agents/skills/nuxt-ui/references/layouts/chat.md +195 -0
- package/.agents/skills/nuxt-ui/references/layouts/dashboard.md +220 -0
- package/.agents/skills/nuxt-ui/references/layouts/docs.md +141 -0
- package/.agents/skills/nuxt-ui/references/layouts/editor.md +167 -0
- package/.agents/skills/nuxt-ui/references/layouts/page.md +260 -0
- package/.agents/skills/nuxt-ui/references/theming.md +427 -0
- package/.agents/skills/supabase-postgres-best-practices/AGENTS.md +68 -0
- package/.agents/skills/supabase-postgres-best-practices/CLAUDE.md +1 -0
- package/.agents/skills/supabase-postgres-best-practices/README.md +116 -0
- package/.agents/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +57 -0
- package/.editorconfig +12 -0
- package/.env.example +2 -0
- package/.eslintignore +1 -0
- package/.prettierrc +9 -0
- package/.vscode/extensions.json +10 -0
- package/.vscode/settings.json +61 -0
- package/README.md +62 -0
- package/app/components/navbar/NavbarAdmin.vue +169 -0
- package/app/composables/auth.ts +81 -0
- package/app/layouts/setup.vue +13 -0
- package/app/middleware/auth.ts +27 -0
- package/app/middleware/setup-check.ts +25 -0
- package/app/pages/admin/(auth)/login.vue +84 -0
- package/app/pages/admin/(auth)/signup.vue +128 -0
- package/app/pages/admin/settings.vue +116 -0
- package/app/pages/admin/setup.vue +300 -0
- package/app/pages/admin.vue +38 -0
- package/bun.lock +2685 -0
- package/eslint.config.mjs +88 -0
- package/nuxt.config.ts +55 -0
- package/package.json +44 -0
- package/public/schema.sql +103 -0
- package/scripts/supabase-typegen.ts +36 -0
- package/server/api/category/list.get.ts +9 -0
- package/server/api/category/new.post.ts +31 -0
- package/server/api/settings/first_setup.get.ts +39 -0
- package/server/api/settings/index.get.ts +27 -0
- package/server/api/settings/update.post.ts +36 -0
- package/server/api/setup/create.post.ts +58 -0
- package/server/api/signup.post.ts +28 -0
- package/server/api/users/[id].get.ts +21 -0
- package/server/api/users/index.get.ts +16 -0
- package/shared/types/supabase.ts +406 -0
- package/skills-lock.json +20 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nuxt
|
|
3
|
+
description: Nuxt full-stack Vue framework with SSR, auto-imports, and file-based routing. Use when working with Nuxt apps, server routes, useFetch, middleware, or hybrid rendering.
|
|
4
|
+
metadata:
|
|
5
|
+
author: Anthony Fu
|
|
6
|
+
version: "2026.1.28"
|
|
7
|
+
source: Generated from https://github.com/nuxt/nuxt, scripts located at https://github.com/antfu/skills
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Nuxt is a full-stack Vue framework that provides server-side rendering, file-based routing, auto-imports, and a powerful module system. It uses Nitro as its server engine for universal deployment across Node.js, serverless, and edge platforms.
|
|
11
|
+
|
|
12
|
+
> The skill is based on Nuxt 3.x, generated at 2026-01-28.
|
|
13
|
+
|
|
14
|
+
## Core
|
|
15
|
+
|
|
16
|
+
| Topic | Description | Reference |
|
|
17
|
+
|-------|-------------|-----------|
|
|
18
|
+
| Directory Structure | Project folder structure, conventions, file organization | [core-directory-structure](references/core-directory-structure.md) |
|
|
19
|
+
| Configuration | nuxt.config.ts, app.config.ts, runtime config, environment variables | [core-config](references/core-config.md) |
|
|
20
|
+
| CLI Commands | Dev server, build, generate, preview, and utility commands | [core-cli](references/core-cli.md) |
|
|
21
|
+
| Routing | File-based routing, dynamic routes, navigation, middleware, layouts | [core-routing](references/core-routing.md) |
|
|
22
|
+
| Data Fetching | useFetch, useAsyncData, $fetch, caching, refresh | [core-data-fetching](references/core-data-fetching.md) |
|
|
23
|
+
| Modules | Creating and using Nuxt modules, Nuxt Kit utilities | [core-modules](references/core-modules.md) |
|
|
24
|
+
| Deployment | Platform-agnostic deployment with Nitro, Vercel, Netlify, Cloudflare | [core-deployment](references/core-deployment.md) |
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
| Topic | Description | Reference |
|
|
29
|
+
|-------|-------------|-----------|
|
|
30
|
+
| Composables Auto-imports | Vue APIs, Nuxt composables, custom composables, utilities | [features-composables](references/features-composables.md) |
|
|
31
|
+
| Components Auto-imports | Component naming, lazy loading, hydration strategies | [features-components-autoimport](references/features-components-autoimport.md) |
|
|
32
|
+
| Built-in Components | NuxtLink, NuxtPage, NuxtLayout, ClientOnly, and more | [features-components](references/features-components.md) |
|
|
33
|
+
| State Management | useState composable, SSR-friendly state, Pinia integration | [features-state](references/features-state.md) |
|
|
34
|
+
| Server Routes | API routes, server middleware, Nitro server engine | [features-server](references/features-server.md) |
|
|
35
|
+
|
|
36
|
+
## Rendering
|
|
37
|
+
|
|
38
|
+
| Topic | Description | Reference |
|
|
39
|
+
|-------|-------------|-----------|
|
|
40
|
+
| Rendering Modes | Universal (SSR), client-side (SPA), hybrid rendering, route rules | [rendering-modes](references/rendering-modes.md) |
|
|
41
|
+
|
|
42
|
+
## Best Practices
|
|
43
|
+
|
|
44
|
+
| Topic | Description | Reference |
|
|
45
|
+
|-------|-------------|-----------|
|
|
46
|
+
| Data Fetching Patterns | Efficient fetching, caching, parallel requests, error handling | [best-practices-data-fetching](references/best-practices-data-fetching.md) |
|
|
47
|
+
| SSR & Hydration | Avoiding context leaks, hydration mismatches, composable patterns | [best-practices-ssr](references/best-practices-ssr.md) |
|
|
48
|
+
|
|
49
|
+
## Advanced
|
|
50
|
+
|
|
51
|
+
| Topic | Description | Reference |
|
|
52
|
+
|-------|-------------|-----------|
|
|
53
|
+
| Layers | Extending applications with reusable layers | [advanced-layers](references/advanced-layers.md) |
|
|
54
|
+
| Lifecycle Hooks | Build-time, runtime, and server hooks | [advanced-hooks](references/advanced-hooks.md) |
|
|
55
|
+
| Module Authoring | Creating publishable Nuxt modules with Nuxt Kit | [advanced-module-authoring](references/advanced-module-authoring.md) |
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lifecycle-hooks
|
|
3
|
+
description: Nuxt and Nitro hooks for extending build-time and runtime behavior
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lifecycle Hooks
|
|
7
|
+
|
|
8
|
+
Nuxt provides hooks to tap into the build process, application lifecycle, and server runtime.
|
|
9
|
+
|
|
10
|
+
## Build-time Hooks (Nuxt)
|
|
11
|
+
|
|
12
|
+
Used in `nuxt.config.ts` or modules:
|
|
13
|
+
|
|
14
|
+
### In nuxt.config.ts
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// nuxt.config.ts
|
|
18
|
+
export default defineNuxtConfig({
|
|
19
|
+
hooks: {
|
|
20
|
+
'build:before': () => {
|
|
21
|
+
console.log('Build starting...')
|
|
22
|
+
},
|
|
23
|
+
'pages:extend': (pages) => {
|
|
24
|
+
// Add custom pages
|
|
25
|
+
pages.push({
|
|
26
|
+
name: 'custom',
|
|
27
|
+
path: '/custom',
|
|
28
|
+
file: '~/pages/custom.vue',
|
|
29
|
+
})
|
|
30
|
+
},
|
|
31
|
+
'components:dirs': (dirs) => {
|
|
32
|
+
// Add component directories
|
|
33
|
+
dirs.push({ path: '~/extra-components' })
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### In Modules
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
// modules/my-module.ts
|
|
43
|
+
export default defineNuxtModule({
|
|
44
|
+
setup(options, nuxt) {
|
|
45
|
+
nuxt.hook('ready', async (nuxt) => {
|
|
46
|
+
console.log('Nuxt is ready')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
nuxt.hook('close', async (nuxt) => {
|
|
50
|
+
console.log('Nuxt is closing')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
nuxt.hook('modules:done', () => {
|
|
54
|
+
console.log('All modules loaded')
|
|
55
|
+
})
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Common Build Hooks
|
|
61
|
+
|
|
62
|
+
| Hook | When |
|
|
63
|
+
|------|------|
|
|
64
|
+
| `ready` | Nuxt initialization complete |
|
|
65
|
+
| `close` | Nuxt is closing |
|
|
66
|
+
| `modules:done` | All modules installed |
|
|
67
|
+
| `build:before` | Before build starts |
|
|
68
|
+
| `build:done` | Build complete |
|
|
69
|
+
| `pages:extend` | Pages routes resolved |
|
|
70
|
+
| `components:dirs` | Component dirs being resolved |
|
|
71
|
+
| `imports:extend` | Auto-imports being resolved |
|
|
72
|
+
| `nitro:config` | Before Nitro config finalized |
|
|
73
|
+
| `vite:extend` | Vite context created |
|
|
74
|
+
| `vite:extendConfig` | Before Vite config finalized |
|
|
75
|
+
|
|
76
|
+
## App Hooks (Runtime)
|
|
77
|
+
|
|
78
|
+
Used in plugins and composables:
|
|
79
|
+
|
|
80
|
+
### In Plugins
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// plugins/lifecycle.ts
|
|
84
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
85
|
+
nuxtApp.hook('app:created', (vueApp) => {
|
|
86
|
+
console.log('Vue app created')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
nuxtApp.hook('app:mounted', (vueApp) => {
|
|
90
|
+
console.log('App mounted')
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
nuxtApp.hook('page:start', () => {
|
|
94
|
+
console.log('Page navigation starting')
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
nuxtApp.hook('page:finish', () => {
|
|
98
|
+
console.log('Page navigation finished')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
nuxtApp.hook('page:loading:start', () => {
|
|
102
|
+
console.log('Page loading started')
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
nuxtApp.hook('page:loading:end', () => {
|
|
106
|
+
console.log('Page loading ended')
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Common App Hooks
|
|
112
|
+
|
|
113
|
+
| Hook | When |
|
|
114
|
+
|------|------|
|
|
115
|
+
| `app:created` | Vue app created |
|
|
116
|
+
| `app:mounted` | Vue app mounted (client only) |
|
|
117
|
+
| `app:error` | Fatal error occurred |
|
|
118
|
+
| `page:start` | Page navigation starting |
|
|
119
|
+
| `page:finish` | Page navigation finished |
|
|
120
|
+
| `page:loading:start` | Loading indicator should show |
|
|
121
|
+
| `page:loading:end` | Loading indicator should hide |
|
|
122
|
+
| `link:prefetch` | Link is being prefetched |
|
|
123
|
+
|
|
124
|
+
### Using Runtime Hooks
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
// composables/usePageTracking.ts
|
|
128
|
+
export function usePageTracking() {
|
|
129
|
+
const nuxtApp = useNuxtApp()
|
|
130
|
+
|
|
131
|
+
nuxtApp.hook('page:finish', () => {
|
|
132
|
+
trackPageView(useRoute().path)
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Server Hooks (Nitro)
|
|
138
|
+
|
|
139
|
+
Used in server plugins:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
// server/plugins/hooks.ts
|
|
143
|
+
export default defineNitroPlugin((nitroApp) => {
|
|
144
|
+
// Modify HTML before sending
|
|
145
|
+
nitroApp.hooks.hook('render:html', (html, { event }) => {
|
|
146
|
+
html.head.push('<meta name="custom" content="value">')
|
|
147
|
+
html.bodyAppend.push('<script>console.log("injected")</script>')
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// Modify response
|
|
151
|
+
nitroApp.hooks.hook('render:response', (response, { event }) => {
|
|
152
|
+
console.log('Sending response:', response.statusCode)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
// Before request
|
|
156
|
+
nitroApp.hooks.hook('request', (event) => {
|
|
157
|
+
console.log('Request:', event.path)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// After response
|
|
161
|
+
nitroApp.hooks.hook('afterResponse', (event) => {
|
|
162
|
+
console.log('Response sent')
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Common Nitro Hooks
|
|
168
|
+
|
|
169
|
+
| Hook | When |
|
|
170
|
+
|------|------|
|
|
171
|
+
| `request` | Request received |
|
|
172
|
+
| `beforeResponse` | Before sending response |
|
|
173
|
+
| `afterResponse` | After response sent |
|
|
174
|
+
| `render:html` | Before HTML is sent |
|
|
175
|
+
| `render:response` | Before response is finalized |
|
|
176
|
+
| `error` | Error occurred |
|
|
177
|
+
|
|
178
|
+
## Custom Hooks
|
|
179
|
+
|
|
180
|
+
### Define Custom Hook Types
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
// types/hooks.d.ts
|
|
184
|
+
import type { HookResult } from '@nuxt/schema'
|
|
185
|
+
|
|
186
|
+
declare module '#app' {
|
|
187
|
+
interface RuntimeNuxtHooks {
|
|
188
|
+
'my-app:event': (data: MyEventData) => HookResult
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
declare module '@nuxt/schema' {
|
|
193
|
+
interface NuxtHooks {
|
|
194
|
+
'my-module:init': () => HookResult
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare module 'nitropack/types' {
|
|
199
|
+
interface NitroRuntimeHooks {
|
|
200
|
+
'my-server:event': (data: any) => void
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Call Custom Hooks
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
// In a plugin
|
|
209
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
210
|
+
// Call custom hook
|
|
211
|
+
nuxtApp.callHook('my-app:event', { type: 'custom' })
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
// In a module
|
|
215
|
+
export default defineNuxtModule({
|
|
216
|
+
setup(options, nuxt) {
|
|
217
|
+
nuxt.callHook('my-module:init')
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## useRuntimeHook
|
|
223
|
+
|
|
224
|
+
Call hooks at runtime from components:
|
|
225
|
+
|
|
226
|
+
```vue
|
|
227
|
+
<script setup lang="ts">
|
|
228
|
+
// Register a callback for a runtime hook
|
|
229
|
+
useRuntimeHook('app:error', (error) => {
|
|
230
|
+
console.error('App error:', error)
|
|
231
|
+
})
|
|
232
|
+
</script>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Hook Examples
|
|
236
|
+
|
|
237
|
+
### Page View Tracking
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
// plugins/analytics.client.ts
|
|
241
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
242
|
+
nuxtApp.hook('page:finish', () => {
|
|
243
|
+
const route = useRoute()
|
|
244
|
+
analytics.track('pageview', {
|
|
245
|
+
path: route.path,
|
|
246
|
+
title: document.title,
|
|
247
|
+
})
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Performance Monitoring
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
// plugins/performance.client.ts
|
|
256
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
257
|
+
let navigationStart: number
|
|
258
|
+
|
|
259
|
+
nuxtApp.hook('page:start', () => {
|
|
260
|
+
navigationStart = performance.now()
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
nuxtApp.hook('page:finish', () => {
|
|
264
|
+
const duration = performance.now() - navigationStart
|
|
265
|
+
console.log(`Navigation took ${duration}ms`)
|
|
266
|
+
})
|
|
267
|
+
})
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Inject HTML
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
// server/plugins/inject.ts
|
|
274
|
+
export default defineNitroPlugin((nitroApp) => {
|
|
275
|
+
nitroApp.hooks.hook('render:html', (html) => {
|
|
276
|
+
html.head.push(`
|
|
277
|
+
<script>
|
|
278
|
+
window.APP_CONFIG = ${JSON.stringify(config)}
|
|
279
|
+
</script>
|
|
280
|
+
`)
|
|
281
|
+
})
|
|
282
|
+
})
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
<!--
|
|
286
|
+
Source references:
|
|
287
|
+
- https://nuxt.com/docs/guide/going-further/hooks
|
|
288
|
+
- https://nuxt.com/docs/api/advanced/hooks
|
|
289
|
+
-->
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nuxt-layers
|
|
3
|
+
description: Extending Nuxt applications with layers for code sharing and reusability
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Nuxt Layers
|
|
7
|
+
|
|
8
|
+
Layers allow sharing and reusing partial Nuxt applications across projects. They can include components, composables, pages, layouts, and configuration.
|
|
9
|
+
|
|
10
|
+
## Using Layers
|
|
11
|
+
|
|
12
|
+
### From npm Package
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
// nuxt.config.ts
|
|
16
|
+
export default defineNuxtConfig({
|
|
17
|
+
extends: [
|
|
18
|
+
'@my-org/base-layer',
|
|
19
|
+
'@nuxtjs/ui-layer',
|
|
20
|
+
],
|
|
21
|
+
})
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### From Git Repository
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// nuxt.config.ts
|
|
28
|
+
export default defineNuxtConfig({
|
|
29
|
+
extends: [
|
|
30
|
+
'github:username/repo',
|
|
31
|
+
'github:username/repo/base', // Subdirectory
|
|
32
|
+
'github:username/repo#v1.0', // Specific tag
|
|
33
|
+
'github:username/repo#dev', // Branch
|
|
34
|
+
'gitlab:username/repo',
|
|
35
|
+
'bitbucket:username/repo',
|
|
36
|
+
],
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### From Local Directory
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// nuxt.config.ts
|
|
44
|
+
export default defineNuxtConfig({
|
|
45
|
+
extends: [
|
|
46
|
+
'../base-layer',
|
|
47
|
+
'./layers/shared',
|
|
48
|
+
],
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Auto-scanned Layers
|
|
53
|
+
|
|
54
|
+
Place in `layers/` directory for automatic discovery:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
my-app/
|
|
58
|
+
├── layers/
|
|
59
|
+
│ ├── base/
|
|
60
|
+
│ │ └── nuxt.config.ts
|
|
61
|
+
│ └── ui/
|
|
62
|
+
│ └── nuxt.config.ts
|
|
63
|
+
└── nuxt.config.ts
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Creating a Layer
|
|
67
|
+
|
|
68
|
+
Minimal layer structure:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
my-layer/
|
|
72
|
+
├── nuxt.config.ts # Required
|
|
73
|
+
├── app/
|
|
74
|
+
│ ├── components/ # Auto-merged
|
|
75
|
+
│ ├── composables/ # Auto-merged
|
|
76
|
+
│ ├── layouts/ # Auto-merged
|
|
77
|
+
│ ├── middleware/ # Auto-merged
|
|
78
|
+
│ ├── pages/ # Auto-merged
|
|
79
|
+
│ ├── plugins/ # Auto-merged
|
|
80
|
+
│ └── app.config.ts # Merged
|
|
81
|
+
├── server/ # Auto-merged
|
|
82
|
+
└── package.json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Layer nuxt.config.ts
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
// my-layer/nuxt.config.ts
|
|
89
|
+
export default defineNuxtConfig({
|
|
90
|
+
// Layer configuration
|
|
91
|
+
app: {
|
|
92
|
+
head: {
|
|
93
|
+
title: 'My Layer App',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
// Shared modules
|
|
97
|
+
modules: ['@nuxt/ui'],
|
|
98
|
+
})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Layer Components
|
|
102
|
+
|
|
103
|
+
```vue
|
|
104
|
+
<!-- my-layer/app/components/BaseButton.vue -->
|
|
105
|
+
<template>
|
|
106
|
+
<button class="base-btn">
|
|
107
|
+
<slot />
|
|
108
|
+
</button>
|
|
109
|
+
</template>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Use in consuming project:
|
|
113
|
+
|
|
114
|
+
```vue
|
|
115
|
+
<template>
|
|
116
|
+
<BaseButton>Click me</BaseButton>
|
|
117
|
+
</template>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Layer Composables
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
// my-layer/app/composables/useTheme.ts
|
|
124
|
+
export function useTheme() {
|
|
125
|
+
const isDark = useState('theme-dark', () => false)
|
|
126
|
+
const toggle = () => isDark.value = !isDark.value
|
|
127
|
+
return { isDark, toggle }
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Layer Priority
|
|
132
|
+
|
|
133
|
+
Override order (highest to lowest):
|
|
134
|
+
1. Your project files
|
|
135
|
+
2. Auto-scanned layers (alphabetically, Z > A)
|
|
136
|
+
3. `extends` array (first > last)
|
|
137
|
+
|
|
138
|
+
Control order with prefixes:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
layers/
|
|
142
|
+
├── 1.base/ # Lower priority
|
|
143
|
+
└── 2.theme/ # Higher priority
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Layer Aliases
|
|
147
|
+
|
|
148
|
+
Access layer files:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
// Auto-scanned layers get aliases
|
|
152
|
+
import Component from '#layers/base/components/Component.vue'
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Named aliases:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
// my-layer/nuxt.config.ts
|
|
159
|
+
export default defineNuxtConfig({
|
|
160
|
+
$meta: {
|
|
161
|
+
name: 'my-layer',
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// In consuming project
|
|
168
|
+
import { something } from '#layers/my-layer/utils'
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Publishing Layers
|
|
172
|
+
|
|
173
|
+
### As npm Package
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"name": "my-nuxt-layer",
|
|
178
|
+
"version": "1.0.0",
|
|
179
|
+
"type": "module",
|
|
180
|
+
"main": "./nuxt.config.ts",
|
|
181
|
+
"dependencies": {
|
|
182
|
+
"@nuxt/ui": "^2.0.0"
|
|
183
|
+
},
|
|
184
|
+
"devDependencies": {
|
|
185
|
+
"nuxt": "^3.0.0"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Private Layers
|
|
191
|
+
|
|
192
|
+
For private git repos:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
export GIGET_AUTH=<github-token>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Layer Best Practices
|
|
199
|
+
|
|
200
|
+
### Use Resolved Paths
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
// my-layer/nuxt.config.ts
|
|
204
|
+
import { fileURLToPath } from 'node:url'
|
|
205
|
+
import { dirname, join } from 'node:path'
|
|
206
|
+
|
|
207
|
+
const currentDir = dirname(fileURLToPath(import.meta.url))
|
|
208
|
+
|
|
209
|
+
export default defineNuxtConfig({
|
|
210
|
+
css: [
|
|
211
|
+
join(currentDir, './assets/main.css'),
|
|
212
|
+
],
|
|
213
|
+
})
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Install Dependencies
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
// nuxt.config.ts
|
|
220
|
+
export default defineNuxtConfig({
|
|
221
|
+
extends: [
|
|
222
|
+
['github:user/layer', { install: true }],
|
|
223
|
+
],
|
|
224
|
+
})
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Disable Layer Modules
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
// nuxt.config.ts
|
|
231
|
+
export default defineNuxtConfig({
|
|
232
|
+
extends: ['./base-layer'],
|
|
233
|
+
// Disable modules from layer
|
|
234
|
+
image: false, // Disables @nuxt/image
|
|
235
|
+
pinia: false, // Disables @pinia/nuxt
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Starter Template
|
|
240
|
+
|
|
241
|
+
Create a new layer:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
npx nuxi init --template layer my-layer
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Example: Theme Layer
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
theme-layer/
|
|
251
|
+
├── nuxt.config.ts
|
|
252
|
+
├── app/
|
|
253
|
+
│ ├── app.config.ts
|
|
254
|
+
│ ├── components/
|
|
255
|
+
│ │ ├── ThemeButton.vue
|
|
256
|
+
│ │ └── ThemeCard.vue
|
|
257
|
+
│ ├── composables/
|
|
258
|
+
│ │ └── useTheme.ts
|
|
259
|
+
│ └── assets/
|
|
260
|
+
│ └── theme.css
|
|
261
|
+
└── package.json
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
// theme-layer/nuxt.config.ts
|
|
266
|
+
export default defineNuxtConfig({
|
|
267
|
+
css: ['~/assets/theme.css'],
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
// theme-layer/app/app.config.ts
|
|
273
|
+
export default defineAppConfig({
|
|
274
|
+
theme: {
|
|
275
|
+
primaryColor: '#00dc82',
|
|
276
|
+
darkMode: false,
|
|
277
|
+
},
|
|
278
|
+
})
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
// consuming-app/nuxt.config.ts
|
|
283
|
+
export default defineNuxtConfig({
|
|
284
|
+
extends: ['theme-layer'],
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
// consuming-app/app/app.config.ts
|
|
288
|
+
export default defineAppConfig({
|
|
289
|
+
theme: {
|
|
290
|
+
primaryColor: '#ff0000', // Override
|
|
291
|
+
},
|
|
292
|
+
})
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
<!--
|
|
296
|
+
Source references:
|
|
297
|
+
- https://nuxt.com/docs/getting-started/layers
|
|
298
|
+
- https://nuxt.com/docs/guide/going-further/layers
|
|
299
|
+
-->
|