0
# Module Development
1
2
Comprehensive utilities for developing Nuxt modules, including configuration, plugins, components, and build system integration. The Nuxt Kit provides everything needed to create powerful, reusable modules for the Nuxt ecosystem.
3
4
## Capabilities
5
6
### Module Definition
7
8
Define and create Nuxt modules with proper typing and lifecycle management.
9
10
```typescript { .api }
11
/**
12
* Define a Nuxt module with proper typing and lifecycle management
13
* @param definition - Module definition object or setup function
14
* @returns Configured Nuxt module
15
*/
16
function defineNuxtModule<OptionsT = Record<string, any>>(
17
definition: ModuleDefinition<OptionsT> | ModuleSetupFunction<OptionsT>
18
): NuxtModule<OptionsT>;
19
20
interface ModuleDefinition<T = Record<string, any>> {
21
/** Module metadata */
22
meta?: ModuleMeta;
23
/** Default options */
24
defaults?: T | ((nuxt: Nuxt) => T);
25
/** Module setup function */
26
setup?: ModuleSetupFunction<T>;
27
/** Module compatibility */
28
compatibility?: NuxtCompatibility;
29
}
30
31
interface ModuleMeta {
32
/** Module name */
33
name?: string;
34
/** Module version */
35
version?: string;
36
/** Module configuration key */
37
configKey?: string;
38
/** Module compatibility info */
39
compatibility?: NuxtCompatibility;
40
}
41
42
type ModuleSetupFunction<T = Record<string, any>> = (
43
resolvedOptions: T,
44
nuxt: Nuxt
45
) => void | Promise<void> | ModuleSetupReturn;
46
47
interface ModuleSetupReturn {
48
/** Timings for performance tracking */
49
timings?: {
50
setup?: number;
51
[key: string]: number | undefined;
52
};
53
}
54
```
55
56
**Usage Examples:**
57
58
```typescript
59
// Basic module definition
60
export default defineNuxtModule({
61
meta: {
62
name: "my-module",
63
configKey: "myModule"
64
},
65
defaults: {
66
enabled: true,
67
apiUrl: "/api"
68
},
69
setup(options, nuxt) {
70
console.log("Setting up my module with options:", options);
71
}
72
});
73
74
// Module with TypeScript options
75
interface MyModuleOptions {
76
enabled: boolean;
77
apiUrl: string;
78
features: {
79
auth: boolean;
80
analytics: boolean;
81
};
82
}
83
84
export default defineNuxtModule<MyModuleOptions>({
85
meta: {
86
name: "my-typed-module",
87
version: "1.0.0",
88
configKey: "myTypedModule"
89
},
90
defaults: {
91
enabled: true,
92
apiUrl: "/api",
93
features: {
94
auth: true,
95
analytics: false
96
}
97
},
98
setup(options, nuxt) {
99
if (!options.enabled) return;
100
101
// Module setup logic
102
addPlugin(createResolver(import.meta.url).resolve("./runtime/plugin"));
103
104
if (options.features.auth) {
105
addServerHandler({
106
route: "/api/auth/**",
107
handler: createResolver(import.meta.url).resolve("./server/auth")
108
});
109
}
110
}
111
});
112
113
// Async module setup
114
export default defineNuxtModule({
115
meta: {
116
name: "async-module"
117
},
118
async setup(options, nuxt) {
119
// Async operations
120
const packageInfo = await readPackageJSON();
121
122
// Add runtime config
123
updateRuntimeConfig({
124
myModule: {
125
version: packageInfo.version
126
}
127
});
128
}
129
});
130
```
131
132
### Context Management
133
134
Access and manage the Nuxt context within modules and utilities.
135
136
```typescript { .api }
137
/**
138
* Get the current Nuxt instance
139
* @returns Current Nuxt instance
140
* @throws Error if called outside Nuxt context
141
*/
142
function useNuxt(): Nuxt;
143
144
/**
145
* Try to get the current Nuxt instance
146
* @returns Current Nuxt instance or null if not available
147
*/
148
function tryUseNuxt(): Nuxt | null;
149
150
/**
151
* Get the current Nuxt context
152
* @returns Nuxt context
153
*/
154
function getNuxtCtx(): NuxtContext;
155
156
/**
157
* Run a function within Nuxt context
158
* @param nuxt - Nuxt instance
159
* @param fn - Function to run
160
* @returns Result of the function
161
*/
162
function runWithNuxtContext<T>(nuxt: Nuxt, fn: () => T): T;
163
164
interface Nuxt {
165
/** Nuxt options */
166
options: NuxtOptions;
167
/** Hook system */
168
hooks: Hookable<NuxtHooks>;
169
/** Module container */
170
moduleContainer: ModuleContainer;
171
/** Call hook */
172
callHook: (name: keyof NuxtHooks, ...args: any[]) => Promise<void>;
173
/** Add hook */
174
hook: (name: keyof NuxtHooks, fn: Function) => void;
175
/** Close Nuxt */
176
close: () => Promise<void>;
177
[key: string]: any;
178
}
179
```
180
181
**Usage Examples:**
182
183
```typescript
184
// Using Nuxt context in utilities
185
function addCustomPlugin() {
186
const nuxt = useNuxt();
187
188
addPlugin({
189
src: createResolver(import.meta.url).resolve("./plugin.js"),
190
mode: "client"
191
});
192
}
193
194
// Safe context access
195
function maybeAddPlugin() {
196
const nuxt = tryUseNuxt();
197
198
if (nuxt) {
199
addPlugin("./plugin.js");
200
}
201
}
202
203
// Running with context
204
async function setupModule(nuxt: Nuxt) {
205
await runWithNuxtContext(nuxt, () => {
206
addPlugin("./plugin.js");
207
addComponent({
208
name: "MyComponent",
209
filePath: "./components/MyComponent.vue"
210
});
211
});
212
}
213
214
// Hook management
215
function registerHooks() {
216
const nuxt = useNuxt();
217
218
nuxt.hook("ready", async () => {
219
console.log("Nuxt is ready!");
220
});
221
222
nuxt.hook("build:before", () => {
223
console.log("Build starting...");
224
});
225
}
226
```
227
228
### Plugin Management
229
230
Add and manage Nuxt plugins programmatically.
231
232
```typescript { .api }
233
/**
234
* Add a plugin to the Nuxt application
235
* @param plugin - Plugin options or path
236
*/
237
function addPlugin(plugin: AddPluginOptions | string): void;
238
239
/**
240
* Add a plugin template with processing
241
* @param pluginOptions - Plugin template options
242
* @returns Added template
243
*/
244
function addPluginTemplate(pluginOptions: NuxtPluginTemplate): NuxtTemplate;
245
246
/**
247
* Normalize plugin options
248
* @param plugin - Plugin to normalize
249
* @returns Normalized plugin
250
*/
251
function normalizePlugin(plugin: NuxtPlugin): NuxtPlugin;
252
253
interface AddPluginOptions {
254
/** Plugin source path */
255
src: string;
256
/** Plugin filename */
257
fileName?: string;
258
/** Plugin mode */
259
mode?: "client" | "server" | "all";
260
/** Plugin options */
261
options?: Record<string, any>;
262
}
263
264
interface NuxtPluginTemplate {
265
/** Template source */
266
src?: string;
267
/** Template filename */
268
filename?: string;
269
/** Template destination */
270
dst?: string;
271
/** Template options */
272
options?: Record<string, any>;
273
/** Template mode */
274
mode?: "client" | "server" | "all";
275
/** Whether plugin should be SSR-friendly */
276
ssr?: boolean;
277
}
278
```
279
280
**Usage Examples:**
281
282
```typescript
283
// Add simple plugin
284
addPlugin("~/plugins/my-plugin.client.js");
285
286
// Add plugin with options
287
addPlugin({
288
src: createResolver(import.meta.url).resolve("./runtime/plugin.js"),
289
mode: "client",
290
options: {
291
apiKey: "abc123"
292
}
293
});
294
295
// Add plugin template
296
addPluginTemplate({
297
src: createResolver(import.meta.url).resolve("./templates/plugin.ejs"),
298
filename: "my-plugin.js",
299
options: {
300
config: moduleOptions
301
}
302
});
303
304
// Add multiple plugins
305
const resolver = createResolver(import.meta.url);
306
307
addPlugin(resolver.resolve("./runtime/composables"));
308
addPlugin({
309
src: resolver.resolve("./runtime/auth.client.js"),
310
mode: "client"
311
});
312
addPlugin({
313
src: resolver.resolve("./runtime/server.server.js"),
314
mode: "server"
315
});
316
```
317
318
### Component Management
319
320
Register and manage components automatically.
321
322
```typescript { .api }
323
/**
324
* Add a component to auto-discovery
325
* @param options - Component registration options
326
*/
327
function addComponent(options: AddComponentOptions): void;
328
329
/**
330
* Add component exports for tree-shaking
331
* @param exports - Component exports to add
332
*/
333
function addComponentExports(exports: ComponentExport[]): void;
334
335
/**
336
* Add a directory for component auto-discovery
337
* @param dir - Directory options
338
*/
339
function addComponentsDir(dir: ComponentsDir): void;
340
341
interface AddComponentOptions {
342
/** Component name */
343
name: string;
344
/** Component file path */
345
filePath: string;
346
/** Export name (for named exports) */
347
export?: string;
348
/** Global registration */
349
global?: boolean;
350
/** Component prefix */
351
prefix?: string;
352
/** Component suffix */
353
suffix?: string;
354
/** Pascal case name */
355
pascalName?: string;
356
/** Kebab case name */
357
kebabName?: string;
358
/** Short name */
359
shortPath?: string;
360
/** Chunk name */
361
chunkName?: string;
362
/** Component mode */
363
mode?: "client" | "server" | "all";
364
/** Island component */
365
island?: boolean;
366
}
367
368
interface ComponentExport {
369
/** Export name */
370
name: string;
371
/** Export source */
372
as?: string;
373
/** Export from */
374
from: string;
375
}
376
377
interface ComponentsDir {
378
/** Directory path */
379
path: string;
380
/** Directory prefix */
381
prefix?: string;
382
/** Directory suffix */
383
suffix?: string;
384
/** Global components */
385
global?: boolean;
386
/** Watch directory */
387
watch?: boolean;
388
/** File extensions */
389
extensions?: string[];
390
/** File patterns */
391
pattern?: string | string[];
392
/** Ignore patterns */
393
ignore?: string[];
394
/** Transpile components */
395
transpile?: boolean;
396
/** Island components */
397
island?: boolean;
398
}
399
```
400
401
**Usage Examples:**
402
403
```typescript
404
// Add single component
405
addComponent({
406
name: "MyButton",
407
filePath: createResolver(import.meta.url).resolve("./runtime/components/MyButton.vue"),
408
global: true
409
});
410
411
// Add component with custom configuration
412
addComponent({
413
name: "LazyChart",
414
filePath: "./components/Chart.vue",
415
mode: "client",
416
prefix: "Lazy",
417
island: true
418
});
419
420
// Add components directory
421
addComponentsDir({
422
path: createResolver(import.meta.url).resolve("./runtime/components"),
423
prefix: "My",
424
global: true
425
});
426
427
// Add component exports for tree-shaking
428
addComponentExports([
429
{ name: "MyButton", from: "./components/MyButton" },
430
{ name: "MyInput", from: "./components/MyInput" },
431
{ name: "default", as: "MyCard", from: "./components/MyCard" }
432
]);
433
434
// Conditional component registration
435
if (moduleOptions.includeUI) {
436
addComponentsDir({
437
path: resolver.resolve("./runtime/ui"),
438
prefix: "UI"
439
});
440
}
441
```
442
443
### Build System Integration
444
445
Integrate with Nuxt's build system using Vite, webpack, and other build tools.
446
447
```typescript { .api }
448
/**
449
* Add a build plugin
450
* @param plugin - Build plugin to add
451
*/
452
function addBuildPlugin(plugin: any): void;
453
454
/**
455
* Add a Vite plugin
456
* @param plugin - Vite plugin to add
457
*/
458
function addVitePlugin(plugin: any): void;
459
460
/**
461
* Add a webpack plugin
462
* @param plugin - Webpack plugin to add
463
*/
464
function addWebpackPlugin(plugin: any): void;
465
466
/**
467
* Extend Vite configuration
468
* @param config - Vite config to merge
469
* @param options - Extension options
470
*/
471
function extendViteConfig(config: any, options?: ExtendConfigOptions): void;
472
473
/**
474
* Extend webpack configuration
475
* @param config - Webpack config to merge
476
* @param options - Extension options
477
*/
478
function extendWebpackConfig(config: any, options?: ExtendConfigOptions): void;
479
480
interface ExtendConfigOptions {
481
/** Development mode only */
482
dev?: boolean;
483
/** Production mode only */
484
build?: boolean;
485
/** Server-side only */
486
server?: boolean;
487
/** Client-side only */
488
client?: boolean;
489
}
490
```
491
492
**Usage Examples:**
493
494
```typescript
495
// Add Vite plugin
496
import { defineNuxtModule } from '@nuxt/kit';
497
import MyVitePlugin from 'my-vite-plugin';
498
499
export default defineNuxtModule({
500
setup() {
501
addVitePlugin(MyVitePlugin({
502
option1: 'value1'
503
}));
504
}
505
});
506
507
// Extend Vite config
508
extendViteConfig({
509
define: {
510
__MODULE_VERSION__: JSON.stringify(moduleVersion)
511
},
512
optimizeDeps: {
513
include: ['my-dependency']
514
}
515
});
516
517
// Add webpack plugin
518
import MyWebpackPlugin from 'my-webpack-plugin';
519
520
addWebpackPlugin(new MyWebpackPlugin({
521
option1: 'value1'
522
}));
523
524
// Conditional build configuration
525
extendViteConfig({
526
build: {
527
rollupOptions: {
528
external: ['external-lib']
529
}
530
}
531
}, { build: true }); // Only in production
532
533
// Add CSS processing
534
extendViteConfig({
535
css: {
536
preprocessorOptions: {
537
scss: {
538
additionalData: `@import "~/assets/styles/variables.scss";`
539
}
540
}
541
}
542
});
543
```
544
545
### Server Integration
546
547
Add server handlers, middleware, and API routes.
548
549
```typescript { .api }
550
/**
551
* Add a server handler
552
* @param handler - Server handler options
553
*/
554
function addServerHandler(handler: {
555
route?: string;
556
handler: string;
557
method?: string;
558
middleware?: boolean;
559
}): void;
560
561
/**
562
* Add development server handler
563
* @param handler - Development server handler options
564
*/
565
function addDevServerHandler(handler: {
566
route?: string;
567
handler: string;
568
method?: string;
569
}): void;
570
571
/**
572
* Add server imports
573
* @param imports - Server imports to add
574
*/
575
function addServerImports(imports: Import[]): void;
576
577
/**
578
* Add server imports directory
579
* @param dirs - Directory paths or options
580
*/
581
function addServerImportsDir(dirs: string | string[]): void;
582
583
/**
584
* Access Nitro instance
585
* @returns Nitro instance
586
*/
587
function useNitro(): Nitro;
588
```
589
590
**Usage Examples:**
591
592
```typescript
593
// Add API route
594
addServerHandler({
595
route: "/api/my-module/**",
596
handler: createResolver(import.meta.url).resolve("./server/api/handler.js")
597
});
598
599
// Add middleware
600
addServerHandler({
601
handler: createResolver(import.meta.url).resolve("./server/middleware/auth.js"),
602
middleware: true
603
});
604
605
// Add development-only handler
606
addDevServerHandler({
607
route: "/api/dev/**",
608
handler: createResolver(import.meta.url).resolve("./server/dev-handler.js")
609
});
610
611
// Add server utils
612
addServerImportsDir(createResolver(import.meta.url).resolve("./server/utils"));
613
614
// Add specific server imports
615
addServerImports([
616
{ name: "myServerUtil", from: createResolver(import.meta.url).resolve("./server/utils") }
617
]);
618
619
// Access Nitro for advanced configuration
620
const nitro = useNitro();
621
nitro.options.runtimeConfig.myModule = moduleOptions;
622
```
623
624
### Module Utilities
625
626
Additional utilities for module development.
627
628
```typescript { .api }
629
/**
630
* Create a path resolver for the module
631
* @param base - Base path (usually import.meta.url)
632
* @returns Resolver functions
633
*/
634
function createResolver(base: string | URL): Resolver;
635
636
/**
637
* Update runtime configuration
638
* @param config - Configuration to merge
639
*/
640
function updateRuntimeConfig(config: Record<string, any>): void;
641
642
/**
643
* Add template
644
* @param template - Template options
645
* @returns Added template
646
*/
647
function addTemplate(template: NuxtTemplate): NuxtTemplate;
648
649
/**
650
* Add type template
651
* @param template - Type template options
652
* @returns Added template
653
*/
654
function addTypeTemplate(template: NuxtTemplate): NuxtTemplate;
655
656
interface Resolver {
657
resolve(...paths: string[]): string;
658
resolvePath(path: string): Promise<string>;
659
}
660
```
661
662
**Usage Examples:**
663
664
```typescript
665
// Module with resolver
666
export default defineNuxtModule({
667
setup() {
668
const resolver = createResolver(import.meta.url);
669
670
// Resolve paths relative to module
671
addPlugin(resolver.resolve("./runtime/plugin.js"));
672
addComponent({
673
name: "MyComponent",
674
filePath: resolver.resolve("./runtime/components/MyComponent.vue")
675
});
676
}
677
});
678
679
// Update runtime config
680
updateRuntimeConfig({
681
myModule: {
682
apiUrl: moduleOptions.apiUrl,
683
version: "1.0.0"
684
}
685
});
686
687
// Add templates
688
addTemplate({
689
filename: "my-module-config.mjs",
690
src: resolver.resolve("./templates/config.ejs"),
691
options: {
692
...moduleOptions
693
}
694
});
695
696
// Add TypeScript definitions
697
addTypeTemplate({
698
filename: "types/my-module.d.ts",
699
src: resolver.resolve("./templates/types.d.ts"),
700
options: moduleOptions
701
});
702
```
703
704
## Complete Module Example
705
706
```typescript
707
import { defineNuxtModule, createResolver, addPlugin, addComponent, addServerHandler, updateRuntimeConfig } from '@nuxt/kit';
708
709
interface ModuleOptions {
710
apiUrl: string;
711
features: {
712
auth: boolean;
713
analytics: boolean;
714
};
715
}
716
717
export default defineNuxtModule<ModuleOptions>({
718
meta: {
719
name: "awesome-module",
720
version: "1.0.0",
721
configKey: "awesomeModule",
722
compatibility: {
723
nuxt: "^3.0.0"
724
}
725
},
726
defaults: {
727
apiUrl: "/api",
728
features: {
729
auth: true,
730
analytics: false
731
}
732
},
733
async setup(options, nuxt) {
734
const resolver = createResolver(import.meta.url);
735
736
// Add runtime config
737
updateRuntimeConfig({
738
awesomeModule: {
739
apiUrl: options.apiUrl
740
}
741
});
742
743
// Add main plugin
744
addPlugin({
745
src: resolver.resolve("./runtime/plugin.js"),
746
options
747
});
748
749
// Add components
750
addComponent({
751
name: "AwesomeButton",
752
filePath: resolver.resolve("./runtime/components/AwesomeButton.vue"),
753
global: true
754
});
755
756
// Conditional features
757
if (options.features.auth) {
758
addServerHandler({
759
route: "/api/auth/**",
760
handler: resolver.resolve("./server/auth.js")
761
});
762
763
addPlugin({
764
src: resolver.resolve("./runtime/auth.client.js"),
765
mode: "client"
766
});
767
}
768
769
if (options.features.analytics) {
770
addPlugin({
771
src: resolver.resolve("./runtime/analytics.js"),
772
options: {
773
trackingId: options.trackingId
774
}
775
});
776
}
777
778
// Development utilities
779
if (nuxt.options.dev) {
780
addDevServerHandler({
781
route: "/api/awesome-dev/**",
782
handler: resolver.resolve("./server/dev.js")
783
});
784
}
785
786
console.log(`✨ Awesome Module initialized with API URL: ${options.apiUrl}`);
787
}
788
});
789
```
790
791
## Types
792
793
```typescript { .api }
794
interface NuxtCompatibility {
795
nuxt?: string;
796
bridge?: boolean;
797
}
798
799
interface ModuleContainer {
800
addModule(module: any, options?: any): Promise<void>;
801
requireModule(module: any, options?: any): Promise<any>;
802
addPlugin(template: any): void;
803
addLayout(template: any, name?: string): void;
804
addServerMiddleware(middleware: any): void;
805
extendBuild(fn: Function): void;
806
extendRoutes(fn: Function): void;
807
}
808
809
interface NuxtContext {
810
nuxt: Nuxt;
811
isStatic: boolean;
812
isDev: boolean;
813
isHMR: boolean;
814
app: any;
815
payload: any;
816
}
817
818
interface Import {
819
name: string;
820
as?: string;
821
from: string;
822
}
823
824
interface Nitro {
825
options: NitroOptions;
826
hooks: Hookable;
827
[key: string]: any;
828
}
829
830
interface NitroOptions {
831
runtimeConfig: Record<string, any>;
832
[key: string]: any;
833
}
834
```