Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Nuxt 3.x reference covering SSR, file-based routing, auto-imports, server routes, and Nitro deployment.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/core-modules.md
1---2name: nuxt-modules3description: Creating and using Nuxt modules to extend framework functionality4---56# Nuxt Modules78Modules extend Nuxt's core functionality. They run at build time and can add components, composables, plugins, and configuration.910## Using Modules1112Install and add to `nuxt.config.ts`:1314```ts15// nuxt.config.ts16export default defineNuxtConfig({17modules: [18// npm package19'@nuxt/ui',20// Local module21'./modules/my-module',22// Inline module23(options, nuxt) => {24console.log('Inline module')25},26// With options27['@nuxt/image', { provider: 'cloudinary' }],28],29})30```3132## Creating Modules3334### Basic Module3536```ts37// modules/my-module.ts38export default defineNuxtModule({39meta: {40name: 'my-module',41configKey: 'myModule',42},43defaults: {44enabled: true,45},46setup(options, nuxt) {47if (!options.enabled) return4849console.log('My module is running!')50},51})52```5354### Adding Components5556```ts57// modules/ui/index.ts58import { addComponent, createResolver } from '@nuxt/kit'5960export default defineNuxtModule({61setup(options, nuxt) {62const { resolve } = createResolver(import.meta.url)6364// Add single component65addComponent({66name: 'MyButton',67filePath: resolve('./runtime/components/MyButton.vue'),68})6970// Add components directory71addComponentsDir({72path: resolve('./runtime/components'),73prefix: 'My',74})75},76})77```7879### Adding Composables8081```ts82// modules/utils/index.ts83import { addImports, createResolver } from '@nuxt/kit'8485export default defineNuxtModule({86setup() {87const { resolve } = createResolver(import.meta.url)8889// Add auto-imported composable90addImports({91name: 'useMyUtil',92from: resolve('./runtime/composables/useMyUtil'),93})9495// Add directory for auto-imports96addImportsDir(resolve('./runtime/composables'))97},98})99```100101### Adding Plugins102103```ts104// modules/analytics/index.ts105import { addPlugin, createResolver } from '@nuxt/kit'106107export default defineNuxtModule({108setup() {109const { resolve } = createResolver(import.meta.url)110111addPlugin({112src: resolve('./runtime/plugin'),113mode: 'client', // 'client', 'server', or 'all'114})115},116})117```118119Plugin file:120121```ts122// modules/analytics/runtime/plugin.ts123export default defineNuxtPlugin((nuxtApp) => {124nuxtApp.hook('page:finish', () => {125console.log('Page loaded')126})127})128```129130### Adding Server Routes131132```ts133// modules/api/index.ts134import { addServerHandler, createResolver } from '@nuxt/kit'135136export default defineNuxtModule({137setup() {138const { resolve } = createResolver(import.meta.url)139140addServerHandler({141route: '/api/my-endpoint',142handler: resolve('./runtime/server/api/my-endpoint'),143})144},145})146```147148### Extending Config149150```ts151// modules/config/index.ts152export default defineNuxtModule({153setup(options, nuxt) {154// Add CSS155nuxt.options.css.push('my-module/styles.css')156157// Add runtime config158nuxt.options.runtimeConfig.public.myModule = {159apiUrl: options.apiUrl,160}161162// Extend Vite config163nuxt.options.vite.optimizeDeps ||= {}164nuxt.options.vite.optimizeDeps.include ||= []165nuxt.options.vite.optimizeDeps.include.push('some-package')166},167})168```169170## Module Hooks171172```ts173export default defineNuxtModule({174setup(options, nuxt) {175// Build-time hooks176nuxt.hook('modules:done', () => {177console.log('All modules loaded')178})179180nuxt.hook('components:dirs', (dirs) => {181dirs.push({ path: '~/extra-components' })182})183184nuxt.hook('pages:extend', (pages) => {185pages.push({186name: 'custom-page',187path: '/custom',188file: resolve('./runtime/pages/custom.vue'),189})190})191192nuxt.hook('imports:extend', (imports) => {193imports.push({ name: 'myHelper', from: 'my-package' })194})195},196})197```198199## Module Options200201Type-safe options with defaults:202203```ts204export interface ModuleOptions {205apiKey: string206enabled?: boolean207prefix?: string208}209210export default defineNuxtModule<ModuleOptions>({211meta: {212name: 'my-module',213configKey: 'myModule',214},215defaults: {216enabled: true,217prefix: 'My',218},219setup(options, nuxt) {220// options is typed as ModuleOptions221if (!options.apiKey) {222console.warn('API key not provided')223}224},225})226```227228Usage:229230```ts231// nuxt.config.ts232export default defineNuxtConfig({233modules: ['my-module'],234myModule: {235apiKey: 'xxx',236prefix: 'Custom',237},238})239```240241## Local Modules242243Place in `modules/` directory:244245```246modules/247├── my-module/248│ ├── index.ts249│ └── runtime/250│ ├── components/251│ ├── composables/252│ └── plugin.ts253```254255Auto-registered or manually added:256257```ts258// nuxt.config.ts259export default defineNuxtConfig({260modules: [261'~/modules/my-module', // Explicit262],263})264```265266## Module Dependencies267268```ts269export default defineNuxtModule({270meta: {271name: 'my-module',272},273moduleDependencies: {274'@nuxt/image': {275version: '>=1.0.0',276defaults: {277provider: 'ipx',278},279},280},281setup() {282// @nuxt/image is guaranteed to be installed283},284})285```286287<!--288Source references:289- https://nuxt.com/docs/guide/modules290- https://nuxt.com/docs/guide/modules/module-anatomy291- https://nuxt.com/docs/api/kit292-->293