0
# Hook System
1
2
The hook system in @nuxt/schema provides comprehensive type definitions for Nuxt's extensible lifecycle events, enabling modules and plugins to integrate seamlessly with the Nuxt build and runtime processes.
3
4
## Core Hook Types
5
6
### HookResult
7
8
```typescript { .api }
9
type HookResult = Promise<void> | void
10
```
11
12
### NuxtHooks Interface
13
14
The complete hook system interface defining all available lifecycle hooks.
15
16
```typescript { .api }
17
interface NuxtHooks {
18
// Compatibility and module system
19
'kit:compatibility': (compatibility: NuxtCompatibility, issues: NuxtCompatibilityIssues) => HookResult
20
21
// Core lifecycle
22
'ready': (nuxt: Nuxt) => HookResult
23
'close': (nuxt: Nuxt) => HookResult
24
'restart': (options?: { hard?: boolean }) => HookResult
25
26
// Build lifecycle
27
'build:before': (nuxt: Nuxt, buildOptions: any) => HookResult
28
'build:done': (nuxt: Nuxt) => HookResult
29
'build:manifest': (manifest: Manifest) => HookResult
30
31
// Module lifecycle
32
'modules:before': () => HookResult
33
'modules:done': () => HookResult
34
35
// App generation
36
'app:resolve': (app: NuxtApp) => HookResult
37
'app:templates': (app: NuxtApp) => HookResult
38
'app:templatesGenerated': (app: NuxtApp, templates: ResolvedNuxtTemplate[], resolver: Function) => HookResult
39
40
// Component system
41
'components:dirs': (dirs: ComponentsDir[]) => HookResult
42
'components:extend': (components: Component[]) => HookResult
43
44
// Import system
45
'imports:sources': (presets: ImportPresetWithDeprecation[]) => HookResult
46
'imports:extend': (imports: Import[]) => HookResult
47
'imports:context': (context: Unimport) => HookResult
48
'imports:dirs': (dirs: string[]) => HookResult
49
50
// Development
51
'dev:ssr-logs': (logs: any[]) => HookResult
52
'webpack:config': (webpackConfigs: Configuration[]) => HookResult
53
'webpack:configResolved': (webpackConfigs: Configuration[]) => HookResult
54
'webpack:compile': (options: { name: string, compiler: Compiler }) => HookResult
55
'webpack:compilation': (compilation: any, compiler: Compiler) => HookResult
56
'webpack:compiled': (options: { name: string, compiler: Compiler, stats: Stats }) => HookResult
57
'webpack:change': (shortPath: string) => HookResult
58
'webpack:error': (error: WebpackError) => HookResult
59
'webpack:done': () => HookResult
60
'webpack:progress': (statesArray: any[]) => HookResult
61
62
// Vite integration
63
'vite:extend': (viteBuildContext: { nuxt: Nuxt, config: ViteConfig }) => HookResult
64
'vite:extendConfig': (viteInlineConfig: ViteUserConfig, env: { isClient: boolean, isServer: boolean }) => HookResult
65
'vite:configResolved': (viteConfig: ResolvedConfig, env: { isClient: boolean, isServer: boolean }) => HookResult
66
'vite:serverCreated': (viteServer: ViteDevServer, env: { isClient: boolean, isServer: boolean }) => HookResult
67
'vite:compiled': () => HookResult
68
69
// Nitro integration
70
'nitro:config': (nitroConfig: NitroConfig) => HookResult
71
'nitro:init': (nitro: Nitro) => HookResult
72
'nitro:build:before': (nitro: Nitro) => HookResult
73
'nitro:build:public-assets': (nitro: Nitro) => HookResult
74
75
// Page and routing
76
'pages:extend': (pages: NuxtPage[]) => HookResult
77
'page:transition:finish': (page?: NuxtPage) => HookResult
78
79
// Generation hooks
80
'generate:before': (generator: any, generateOptions: any) => HookResult
81
'generate:done': (generator: any, generateOptions: any) => HookResult
82
'generate:page': (page: { route: string, path: string, html: string, errors: any[] }) => HookResult
83
'generate:routeCreated': (route: string, path: string, errors: any[]) => HookResult
84
'generate:routeFailed': (route: string, errors: any[]) => HookResult
85
86
// Server and rendering
87
'render:errorMiddleware': (app: any) => HookResult
88
'render:route': (url: string, result: any, context: any) => HookResult
89
'server:devHandler': (handler: EventHandler) => HookResult
90
'server:devMiddleware': (middleware: any) => HookResult
91
}
92
```
93
94
## Hook Categories
95
96
### Lifecycle Hooks
97
98
Core application lifecycle events.
99
100
```typescript { .api }
101
interface LifecycleHooks {
102
'ready': (nuxt: Nuxt) => HookResult
103
'close': (nuxt: Nuxt) => HookResult
104
'restart': (options?: { hard?: boolean }) => HookResult
105
'modules:before': () => HookResult
106
'modules:done': () => HookResult
107
}
108
```
109
110
### Build Hooks
111
112
Build process and bundler integration.
113
114
```typescript { .api }
115
interface BuildHooks {
116
'build:before': (nuxt: Nuxt, buildOptions: any) => HookResult
117
'build:done': (nuxt: Nuxt) => HookResult
118
'build:manifest': (manifest: Manifest) => HookResult
119
'webpack:config': (webpackConfigs: Configuration[]) => HookResult
120
'vite:extend': (viteBuildContext: { nuxt: Nuxt, config: ViteConfig }) => HookResult
121
}
122
```
123
124
### Development Hooks
125
126
Development server and hot module replacement.
127
128
```typescript { .api }
129
interface DevHooks {
130
'dev:ssr-logs': (logs: any[]) => HookResult
131
'webpack:change': (shortPath: string) => HookResult
132
'vite:serverCreated': (viteServer: ViteDevServer, env: { isClient: boolean, isServer: boolean }) => HookResult
133
'server:devHandler': (handler: EventHandler) => HookResult
134
}
135
```
136
137
## Hook Usage Patterns
138
139
### In Nuxt Configuration
140
141
```typescript
142
import type { NuxtHooks } from '@nuxt/schema';
143
144
export default defineNuxtConfig({
145
hooks: {
146
'ready': async (nuxt) => {
147
console.log('Nuxt is ready!');
148
},
149
150
'build:before': async (nuxt, buildOptions) => {
151
// Modify build options before build starts
152
console.log('Starting build process');
153
},
154
155
'components:extend': async (components) => {
156
// Modify component registration
157
components.push({
158
pascalName: 'MyCustomComponent',
159
kebabName: 'my-custom-component',
160
export: 'default',
161
filePath: '~/components/custom/MyComponent.vue',
162
shortPath: 'components/custom/MyComponent.vue',
163
chunkName: 'components/my-custom-component',
164
prefetch: false,
165
preload: false
166
});
167
},
168
169
'imports:extend': async (imports) => {
170
// Add custom auto-imports
171
imports.push({
172
name: 'myUtility',
173
from: '~/utils/my-utility'
174
});
175
}
176
} satisfies Partial<NuxtHooks>
177
});
178
```
179
180
### In Nuxt Modules
181
182
```typescript
183
import type { NuxtModule, NuxtHooks } from '@nuxt/schema';
184
185
const myModule: NuxtModule = {
186
meta: {
187
name: 'my-module'
188
},
189
setup(options, nuxt) {
190
// Hook into build process
191
nuxt.hook('build:before', async () => {
192
console.log('Module preparing for build');
193
});
194
195
// Extend webpack configuration
196
nuxt.hook('webpack:config', async (configs) => {
197
for (const config of configs) {
198
config.resolve = config.resolve || {};
199
config.resolve.alias = {
200
...config.resolve.alias,
201
'@my-module': path.resolve(__dirname, './runtime')
202
};
203
}
204
});
205
206
// Add custom pages
207
nuxt.hook('pages:extend', async (pages) => {
208
pages.push({
209
name: 'admin-dashboard',
210
path: '/admin',
211
file: path.resolve(__dirname, './pages/admin.vue')
212
});
213
});
214
215
// Register components
216
nuxt.hook('components:dirs', async (dirs) => {
217
dirs.push({
218
path: path.resolve(__dirname, './components'),
219
prefix: 'MyModule'
220
});
221
});
222
}
223
};
224
```
225
226
### Hook Utilities
227
228
```typescript
229
// Type-safe hook registration
230
function registerHooks(nuxt: Nuxt, hooks: Partial<NuxtHooks>) {
231
for (const [name, handler] of Object.entries(hooks)) {
232
nuxt.hook(name as keyof NuxtHooks, handler);
233
}
234
}
235
236
// Hook middleware pattern
237
function createHookMiddleware<T extends keyof NuxtHooks>(
238
hookName: T,
239
middleware: (args: Parameters<NuxtHooks[T]>) => void
240
) {
241
return (nuxt: Nuxt) => {
242
nuxt.hook(hookName, (...args) => {
243
middleware(args);
244
});
245
};
246
}
247
```
248
249
### Advanced Hook Patterns
250
251
```typescript
252
// Conditional hook registration
253
const myModule: NuxtModule = {
254
setup(options, nuxt) {
255
// Only register hooks in development
256
if (nuxt.options.dev) {
257
nuxt.hook('webpack:change', async (shortPath) => {
258
console.log(`File changed: ${shortPath}`);
259
});
260
261
nuxt.hook('dev:ssr-logs', async (logs) => {
262
// Process development logs
263
logs.forEach(log => console.log(log));
264
});
265
}
266
267
// Build-specific hooks
268
nuxt.hook('build:before', async () => {
269
// Prepare build assets
270
await generateBuildAssets();
271
});
272
273
// Async hook with error handling
274
nuxt.hook('ready', async () => {
275
try {
276
await initializeExternalService();
277
} catch (error) {
278
console.error('Failed to initialize service:', error);
279
}
280
});
281
}
282
};
283
```
284
285
### Hook Context and State
286
287
```typescript
288
// Sharing state between hooks
289
const moduleState = {
290
initialized: false,
291
components: new Set<string>()
292
};
293
294
nuxt.hook('components:extend', async (components) => {
295
components.forEach(component => {
296
moduleState.components.add(component.pascalName);
297
});
298
});
299
300
nuxt.hook('ready', async () => {
301
moduleState.initialized = true;
302
console.log(`Registered ${moduleState.components.size} components`);
303
});
304
```
305
306
The hook system provides a powerful way to extend Nuxt's functionality at every stage of the application lifecycle, from initial setup through build time to runtime, all with complete type safety.