@plutocms/supabase 0.0.1-alpha.9 → 0.1.0

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.
Files changed (102) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/README.md +2 -4
  3. package/app/assets/css/tailwind.css +5 -0
  4. package/app/components/navbar/NavbarAdmin.vue +6 -5
  5. package/app/composables/auth.ts +124 -2
  6. package/app/middleware/auth.ts +9 -6
  7. package/app/middleware/setup-check.ts +25 -21
  8. package/app/pages/admin/(auth)/confirm.vue +38 -0
  9. package/app/pages/admin/(auth)/forgot-password.vue +88 -0
  10. package/app/pages/admin/(auth)/login.vue +5 -1
  11. package/app/pages/admin/(auth)/signup.vue +76 -16
  12. package/app/pages/admin/(auth)/update-password.vue +134 -0
  13. package/app/pages/admin/setup.vue +5 -142
  14. package/app/pages/admin.vue +2 -4
  15. package/modules/pluto-migrations.ts +121 -0
  16. package/nuxt.config.ts +14 -1
  17. package/package.json +40 -24
  18. package/public/schema.sql +46 -5
  19. package/scripts/supabase-typegen.ts +36 -21
  20. package/scripts/tsconfig.json +18 -0
  21. package/server/api/{signup.post.ts → auth/signup.post.ts} +7 -16
  22. package/server/api/setup/create.post.ts +39 -82
  23. package/server/plugins/migrations.ts +60 -0
  24. package/server/utils/migrations.ts +88 -0
  25. package/server/utils/sql.ts +81 -0
  26. package/server/utils/typegen.ts +68 -0
  27. package/shared/types/runtime-config.d.ts +16 -0
  28. package/shared/types/supabase.ts +90 -117
  29. package/.agents/skills/nuxt/GENERATION.md +0 -5
  30. package/.agents/skills/nuxt/SKILL.md +0 -55
  31. package/.agents/skills/nuxt/references/advanced-hooks.md +0 -289
  32. package/.agents/skills/nuxt/references/advanced-layers.md +0 -299
  33. package/.agents/skills/nuxt/references/advanced-module-authoring.md +0 -554
  34. package/.agents/skills/nuxt/references/best-practices-data-fetching.md +0 -357
  35. package/.agents/skills/nuxt/references/best-practices-ssr.md +0 -355
  36. package/.agents/skills/nuxt/references/core-cli.md +0 -263
  37. package/.agents/skills/nuxt/references/core-config.md +0 -162
  38. package/.agents/skills/nuxt/references/core-data-fetching.md +0 -236
  39. package/.agents/skills/nuxt/references/core-deployment.md +0 -224
  40. package/.agents/skills/nuxt/references/core-directory-structure.md +0 -269
  41. package/.agents/skills/nuxt/references/core-modules.md +0 -292
  42. package/.agents/skills/nuxt/references/core-routing.md +0 -226
  43. package/.agents/skills/nuxt/references/features-components-autoimport.md +0 -328
  44. package/.agents/skills/nuxt/references/features-components.md +0 -264
  45. package/.agents/skills/nuxt/references/features-composables.md +0 -276
  46. package/.agents/skills/nuxt/references/features-server.md +0 -265
  47. package/.agents/skills/nuxt/references/features-state.md +0 -194
  48. package/.agents/skills/nuxt/references/rendering-modes.md +0 -237
  49. package/.agents/skills/nuxt-ui/SKILL.md +0 -334
  50. package/.agents/skills/nuxt-ui/references/components.md +0 -377
  51. package/.agents/skills/nuxt-ui/references/composables.md +0 -127
  52. package/.agents/skills/nuxt-ui/references/layouts/chat.md +0 -195
  53. package/.agents/skills/nuxt-ui/references/layouts/dashboard.md +0 -220
  54. package/.agents/skills/nuxt-ui/references/layouts/docs.md +0 -141
  55. package/.agents/skills/nuxt-ui/references/layouts/editor.md +0 -167
  56. package/.agents/skills/nuxt-ui/references/layouts/page.md +0 -260
  57. package/.agents/skills/nuxt-ui/references/theming.md +0 -427
  58. package/.agents/skills/supabase-postgres-best-practices/AGENTS.md +0 -68
  59. package/.agents/skills/supabase-postgres-best-practices/CLAUDE.md +0 -1
  60. package/.agents/skills/supabase-postgres-best-practices/README.md +0 -116
  61. package/.agents/skills/supabase-postgres-best-practices/SKILL.md +0 -64
  62. package/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +0 -55
  63. package/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +0 -49
  64. package/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +0 -46
  65. package/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +0 -44
  66. package/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +0 -41
  67. package/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +0 -46
  68. package/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +0 -54
  69. package/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +0 -53
  70. package/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +0 -50
  71. package/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +0 -50
  72. package/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +0 -56
  73. package/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +0 -68
  74. package/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +0 -50
  75. package/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +0 -54
  76. package/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +0 -45
  77. package/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +0 -55
  78. package/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +0 -55
  79. package/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +0 -44
  80. package/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +0 -40
  81. package/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +0 -48
  82. package/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +0 -43
  83. package/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +0 -45
  84. package/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +0 -80
  85. package/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +0 -46
  86. package/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +0 -59
  87. package/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +0 -55
  88. package/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +0 -55
  89. package/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +0 -61
  90. package/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +0 -54
  91. package/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +0 -50
  92. package/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +0 -57
  93. package/.editorconfig +0 -12
  94. package/.eslintignore +0 -1
  95. package/.prettierrc +0 -9
  96. package/.vscode/extensions.json +0 -10
  97. package/.vscode/settings.json +0 -61
  98. package/bun.lock +0 -2837
  99. package/eslint.config.mjs +0 -88
  100. package/server/api/category/list.get.ts +0 -9
  101. package/server/api/category/new.post.ts +0 -31
  102. package/skills-lock.json +0 -20
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Splits a SQL string into individual statements, correctly handling
3
+ * $$ dollar-quoted blocks, single-quoted strings, and -- comments.
4
+ */
5
+ export function splitStatements(sql: string): string[] {
6
+ const statements: string[] = []
7
+ let current = ''
8
+ let i = 0
9
+
10
+ while (i < sql.length) {
11
+ // Check for dollar-quoting ($$)
12
+ if (sql[i] === '$' && sql[i + 1] === '$') {
13
+ current += '$$'
14
+ i += 2
15
+ // Read until closing $$
16
+ while (i < sql.length) {
17
+ if (sql[i] === '$' && sql[i + 1] === '$') {
18
+ current += '$$'
19
+ i += 2
20
+ break
21
+ }
22
+ current += sql[i]
23
+ i++
24
+ }
25
+ continue
26
+ }
27
+
28
+ // Check for single-quoted strings (handle '' escapes)
29
+ if (sql[i] === `'`) {
30
+ current += sql[i]
31
+ i++
32
+ while (i < sql.length) {
33
+ if (sql[i] === `'` && sql[i + 1] === `'`) {
34
+ // Escaped quote
35
+ current += `''`
36
+ i += 2
37
+ continue
38
+ }
39
+ if (sql[i] === `'`) {
40
+ current += sql[i]
41
+ i++
42
+ break
43
+ }
44
+ current += sql[i]
45
+ i++
46
+ }
47
+ continue
48
+ }
49
+
50
+ // Check for single-line comments
51
+ if (sql[i] === '-' && sql[i + 1] === '-') {
52
+ while (i < sql.length && sql[i] !== '\n') {
53
+ current += sql[i]
54
+ i++
55
+ }
56
+ continue
57
+ }
58
+
59
+ // Statement terminator
60
+ if (sql[i] === ';') {
61
+ current += ';'
62
+ const trimmed = current.trim()
63
+ if (trimmed && trimmed !== ';') {
64
+ statements.push(trimmed)
65
+ }
66
+ current = ''
67
+ i++
68
+ continue
69
+ }
70
+
71
+ current += sql[i]
72
+ i++
73
+ }
74
+
75
+ const trimmed = current.trim()
76
+ if (trimmed && trimmed !== ';') {
77
+ statements.push(trimmed)
78
+ }
79
+
80
+ return statements
81
+ }
@@ -0,0 +1,68 @@
1
+ import { execFile } from 'node:child_process'
2
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs'
3
+ import { join } from 'node:path'
4
+ import { promisify } from 'node:util'
5
+
6
+ const execFileAsync = promisify(execFile)
7
+
8
+ /**
9
+ * Resolves the local `supabase` CLI binary from node_modules/.bin so
10
+ * generation works from within the Nitro dev server without relying on
11
+ * `bunx`/`npx` (and without requiring `supabase login`, since we connect
12
+ * directly via --db-url).
13
+ */
14
+ function resolveSupabaseBin(rootDir: string): string {
15
+ const binName = process.platform === 'win32' ? 'supabase.cmd' : 'supabase'
16
+ const localBin = join(rootDir, 'node_modules/.bin', binName)
17
+ return existsSync(localBin) ? localBin : 'supabase'
18
+ }
19
+
20
+ /**
21
+ * Regenerates the Supabase `Database` types from the live database schema
22
+ * and writes them to <rootDir>/shared/types/supabase.ts, only touching the
23
+ * file if the content actually changed (avoids needless dev-server reloads).
24
+ *
25
+ * Never throws — failures are logged and swallowed so this can safely run
26
+ * as a side effect of the migrations plugin without breaking server boot.
27
+ */
28
+ export async function regenerateSupabaseTypes(
29
+ rootDir: string,
30
+ connectionString?: string
31
+ ): Promise<void> {
32
+ const connStr = connectionString ?? process.env.DATABASE_URL
33
+
34
+ if (!connStr) {
35
+ console.warn(
36
+ '[typegen] Skipping Supabase type generation: no DATABASE_URL configured.'
37
+ )
38
+ return
39
+ }
40
+
41
+ const targetPath = join(rootDir, 'shared/types/supabase.ts')
42
+
43
+ try {
44
+ const { stdout } = await execFileAsync(
45
+ resolveSupabaseBin(rootDir),
46
+ ['gen', 'types', 'typescript', '--db-url', connStr, '--schema', 'public'],
47
+ { maxBuffer: 1024 * 1024 * 16 }
48
+ )
49
+
50
+ if (!stdout.trim()) {
51
+ console.warn('[typegen] Supabase CLI returned no output, skipping write.')
52
+ return
53
+ }
54
+
55
+ const existing = existsSync(targetPath)
56
+ ? readFileSync(targetPath, 'utf-8')
57
+ : null
58
+
59
+ if (existing === stdout) {
60
+ return
61
+ }
62
+
63
+ writeFileSync(targetPath, stdout, 'utf-8')
64
+ console.warn(`[typegen] Regenerated Supabase types at ${targetPath}`)
65
+ } catch (error) {
66
+ console.warn('[typegen] Failed to regenerate Supabase types:', error)
67
+ }
68
+ }
@@ -0,0 +1,16 @@
1
+ // Nuxt infers runtimeConfig types from the actual merged value at build
2
+ // time, which narrows `plutoLayerSchemas` to whatever layer keys happen
3
+ // to be discovered in a given project (e.g. `{ "supabase-shop": string }`)
4
+ // instead of the general `Record<string, string>` declared in
5
+ // nuxt.config.ts. This augmentation pins the intended, stable shape.
6
+ // Lives under shared/ so it's picked up by the app, server, and shared
7
+ // TS projects alike (layer-root .d.ts files are only included by the
8
+ // shared project).
9
+ declare module '@nuxt/schema' {
10
+ interface RuntimeConfig {
11
+ plutoRootDir: string
12
+ plutoLayerSchemas: Record<string, string>
13
+ }
14
+ }
15
+
16
+ export {}
@@ -10,95 +10,125 @@ export type Database = {
10
10
  // Allows to automatically instantiate createClient with right options
11
11
  // instead of createClient<Database, { PostgrestVersion: 'XX' }>(URL, KEY)
12
12
  __InternalSupabase: {
13
- PostgrestVersion: "12.2.12 (cd3cf9e)"
13
+ PostgrestVersion: "14.1"
14
14
  }
15
15
  public: {
16
16
  Tables: {
17
- availability: {
17
+ healthcheck: {
18
18
  Row: {
19
- created_at: string
19
+ config_name: Database["public"]["Enums"]["thealthcheck"]
20
+ config_value: string
20
21
  id: number
21
- label: string | null
22
- slug: string | null
23
22
  }
24
23
  Insert: {
25
- created_at?: string
24
+ config_name: Database["public"]["Enums"]["thealthcheck"]
25
+ config_value: string
26
26
  id?: number
27
- label?: string | null
28
- slug?: string | null
29
27
  }
30
28
  Update: {
31
- created_at?: string
29
+ config_name?: Database["public"]["Enums"]["thealthcheck"]
30
+ config_value?: string
32
31
  id?: number
33
- label?: string | null
34
- slug?: string | null
35
32
  }
36
33
  Relationships: []
37
34
  }
38
- categories: {
35
+ pluto_migrations: {
39
36
  Row: {
40
- description: string | null
37
+ applied_at: string
38
+ id: number
39
+ layer_name: string
40
+ }
41
+ Insert: {
42
+ applied_at?: string
43
+ id?: number
44
+ layer_name: string
45
+ }
46
+ Update: {
47
+ applied_at?: string
48
+ id?: number
49
+ layer_name?: string
50
+ }
51
+ Relationships: []
52
+ }
53
+ product_availability: {
54
+ Row: {
55
+ created_at: string
41
56
  id: number
42
57
  label: string
43
58
  slug: string
44
59
  }
45
60
  Insert: {
46
- description?: string | null
47
- id?: number
61
+ created_at?: string
62
+ id?: never
48
63
  label: string
49
64
  slug: string
50
65
  }
51
66
  Update: {
52
- description?: string | null
53
- id?: number
67
+ created_at?: string
68
+ id?: never
54
69
  label?: string
55
70
  slug?: string
56
71
  }
57
72
  Relationships: []
58
73
  }
59
- healthcheck: {
74
+ product_category: {
60
75
  Row: {
61
- config_name: Database["public"]["Enums"]["Healthcheck"]
62
- config_value: string | null
76
+ description: string | null
63
77
  id: number
78
+ label: string
79
+ slug: string
64
80
  }
65
81
  Insert: {
66
- config_name: Database["public"]["Enums"]["Healthcheck"]
67
- config_value?: string | null
68
- id?: number
82
+ description?: string | null
83
+ id?: never
84
+ label: string
85
+ slug: string
69
86
  }
70
87
  Update: {
71
- config_name?: Database["public"]["Enums"]["Healthcheck"]
72
- config_value?: string | null
73
- id?: number
88
+ description?: string | null
89
+ id?: never
90
+ label?: string
91
+ slug?: string
74
92
  }
75
93
  Relationships: []
76
94
  }
77
- media: {
95
+ product_media: {
78
96
  Row: {
79
97
  alt: string | null
80
98
  created_at: string
81
99
  id: number
82
- name: string | null
100
+ mime_type: string | null
101
+ name: string
83
102
  product_id: number | null
103
+ size: number | null
104
+ storage_path: string | null
105
+ url: string | null
84
106
  }
85
107
  Insert: {
86
108
  alt?: string | null
87
109
  created_at?: string
88
- id?: number
89
- name?: string | null
110
+ id?: never
111
+ mime_type?: string | null
112
+ name: string
90
113
  product_id?: number | null
114
+ size?: number | null
115
+ storage_path?: string | null
116
+ url?: string | null
91
117
  }
92
118
  Update: {
93
119
  alt?: string | null
94
120
  created_at?: string
95
- id?: number
96
- name?: string | null
121
+ id?: never
122
+ mime_type?: string | null
123
+ name?: string
97
124
  product_id?: number | null
125
+ size?: number | null
126
+ storage_path?: string | null
127
+ url?: string | null
98
128
  }
99
129
  Relationships: [
100
130
  {
101
- foreignKeyName: "media_product_id_fkey"
131
+ foreignKeyName: "product_media_product_id_fkey"
102
132
  columns: ["product_id"]
103
133
  isOneToOne: false
104
134
  referencedRelation: "products"
@@ -106,56 +136,6 @@ export type Database = {
106
136
  },
107
137
  ]
108
138
  }
109
- posts: {
110
- Row: {
111
- author_id: string
112
- content: string | null
113
- created_at: string
114
- deleted_at: string | null
115
- excerpt: string | null
116
- id: number
117
- is_draft: boolean | null
118
- published_at: string | null
119
- slug: string
120
- title: string | null
121
- updated_at: string | null
122
- }
123
- Insert: {
124
- author_id: string
125
- content?: string | null
126
- created_at?: string
127
- deleted_at?: string | null
128
- excerpt?: string | null
129
- id?: number
130
- is_draft?: boolean | null
131
- published_at?: string | null
132
- slug: string
133
- title?: string | null
134
- updated_at?: string | null
135
- }
136
- Update: {
137
- author_id?: string
138
- content?: string | null
139
- created_at?: string
140
- deleted_at?: string | null
141
- excerpt?: string | null
142
- id?: number
143
- is_draft?: boolean | null
144
- published_at?: string | null
145
- slug?: string
146
- title?: string | null
147
- updated_at?: string | null
148
- }
149
- Relationships: [
150
- {
151
- foreignKeyName: "posts_author_id_fkey"
152
- columns: ["author_id"]
153
- isOneToOne: true
154
- referencedRelation: "profiles"
155
- referencedColumns: ["id"]
156
- },
157
- ]
158
- }
159
139
  products: {
160
140
  Row: {
161
141
  availability: number | null
@@ -172,9 +152,9 @@ export type Database = {
172
152
  Insert: {
173
153
  availability?: number | null
174
154
  category?: number | null
175
- created_at: string
155
+ created_at?: string
176
156
  description?: string | null
177
- id?: number
157
+ id?: never
178
158
  is_custom?: boolean
179
159
  name: string
180
160
  price: number
@@ -186,7 +166,7 @@ export type Database = {
186
166
  category?: number | null
187
167
  created_at?: string
188
168
  description?: string | null
189
- id?: number
169
+ id?: never
190
170
  is_custom?: boolean
191
171
  name?: string
192
172
  price?: number
@@ -198,53 +178,59 @@ export type Database = {
198
178
  foreignKeyName: "products_availability_fkey"
199
179
  columns: ["availability"]
200
180
  isOneToOne: false
201
- referencedRelation: "availability"
181
+ referencedRelation: "product_availability"
202
182
  referencedColumns: ["id"]
203
183
  },
204
184
  {
205
185
  foreignKeyName: "products_category_fkey"
206
186
  columns: ["category"]
207
187
  isOneToOne: false
208
- referencedRelation: "categories"
188
+ referencedRelation: "product_category"
209
189
  referencedColumns: ["id"]
210
190
  },
211
191
  ]
212
192
  }
213
193
  profiles: {
214
194
  Row: {
215
- first_name: string | null
195
+ display_name: string | null
196
+ email: string | null
216
197
  id: string
217
- is_admin: boolean | null
218
- last_name: string | null
198
+ is_admin: boolean
199
+ updated_at: string | null
200
+ username: string | null
219
201
  }
220
202
  Insert: {
221
- first_name?: string | null
203
+ display_name?: string | null
204
+ email?: string | null
222
205
  id: string
223
- is_admin?: boolean | null
224
- last_name?: string | null
206
+ is_admin?: boolean
207
+ updated_at?: string | null
208
+ username?: string | null
225
209
  }
226
210
  Update: {
227
- first_name?: string | null
211
+ display_name?: string | null
212
+ email?: string | null
228
213
  id?: string
229
- is_admin?: boolean | null
230
- last_name?: string | null
214
+ is_admin?: boolean
215
+ updated_at?: string | null
216
+ username?: string | null
231
217
  }
232
218
  Relationships: []
233
219
  }
234
220
  settings: {
235
221
  Row: {
236
222
  id: number
237
- setting_name: Database["public"]["Enums"]["Settings"]
223
+ setting_name: Database["public"]["Enums"]["tsettings"]
238
224
  setting_value: string
239
225
  }
240
226
  Insert: {
241
227
  id?: number
242
- setting_name: Database["public"]["Enums"]["Settings"]
228
+ setting_name: Database["public"]["Enums"]["tsettings"]
243
229
  setting_value: string
244
230
  }
245
231
  Update: {
246
232
  id?: number
247
- setting_name?: Database["public"]["Enums"]["Settings"]
233
+ setting_name?: Database["public"]["Enums"]["tsettings"]
248
234
  setting_value?: string
249
235
  }
250
236
  Relationships: []
@@ -257,14 +243,8 @@ export type Database = {
257
243
  [_ in never]: never
258
244
  }
259
245
  Enums: {
260
- Availability: "preorder" | "in_stock"
261
- Healthcheck: "first_setup"
262
- Settings:
263
- | "admin_email"
264
- | "website_description"
265
- | "website_title"
266
- | "website_url"
267
- | "users_can_register"
246
+ thealthcheck: "first_setup"
247
+ tsettings: "website_title" | "website_url" | "website_description"
268
248
  }
269
249
  CompositeTypes: {
270
250
  [_ in never]: never
@@ -392,15 +372,8 @@ export type CompositeTypes<
392
372
  export const Constants = {
393
373
  public: {
394
374
  Enums: {
395
- Availability: ["preorder", "in_stock"],
396
- Healthcheck: ["first_setup"],
397
- Settings: [
398
- "admin_email",
399
- "website_description",
400
- "website_title",
401
- "website_url",
402
- "users_can_register",
403
- ],
375
+ thealthcheck: ["first_setup"],
376
+ tsettings: ["website_title", "website_url", "website_description"],
404
377
  },
405
378
  },
406
379
  } as const
@@ -1,5 +0,0 @@
1
- # Generation Info
2
-
3
- - **Source:** `sources/nuxt`
4
- - **Git SHA:** `c9fed804b9bef362276033b03ca43730c6efa7dc`
5
- - **Generated:** 2026-01-28
@@ -1,55 +0,0 @@
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) |