Skip to main content
Here are some common patterns used by module authors to add functionality to Nuxt applications.

Modify Nuxt Configuration

Nuxt configuration can be read and altered by modules. Here’s an example of a module enabling an experimental feature.
When you need to handle more complex configuration alterations, you should consider using defu.

Expose Options to Runtime

Because modules aren’t part of the application runtime, their options aren’t either. However, in many cases, you might need access to some of these module options within your runtime code. We recommend exposing the needed config using Nuxt’s runtimeConfig.
Note that we use defu to extend the public runtime configuration the user provides instead of overwriting it. You can then access your module options in a plugin, component, the application like any other runtime configuration:
Be careful not to expose any sensitive module configuration on the public runtime config, such as private API keys, as they will end up in the public bundle.

Add Plugins

Plugins are a common way for a module to add runtime logic. You can use the addPlugin utility to register them from your module.

Add Components

If your module should provide Vue components, you can use the addComponent utility to add them as auto-imports for Nuxt to resolve.
Alternatively, you can add an entire directory by using addComponentsDir.
It is highly recommended to prefix your exports to avoid conflicts with user code or other modules. See Prefix Your Exports for more details.
Note that all components, pages, composables and other files that would be normally placed in your app/ folder need to be in runtime/app/. This will mean they can be type checked properly.

Add Composables

If your module should provide composables, you can use the addImports utility to add them as auto-imports for Nuxt to resolve.
Multiple entries can be passed as an array:
Alternatively, you can add an entire directory by using addImportsDir.

Add Keyed Functions

Sometimes, you may need to maintain state consistency between the server and the client. Examples include Nuxt’s built-in useState or useAsyncData composables. When a function is registered, Nuxt’s compiler automatically injects a unique key as an additional argument if the function is called with fewer than the specified number of arguments. This key remains stable between server-side rendering and client hydration.
The injected key is a hash derived from the file path and call location.
Use the keyedComposables option to register your function:
The keyedComposables configuration accepts an array of objects with the following properties: For example, with argumentLength: 2:

Add Server Routes

You can add server routes to your module using the addServerHandler utility.
You can also add a dynamic server route:
It is highly recommended to prefix your server routes to avoid conflicts with user-defined routes. Common paths like /api/auth, /api/login, or /api/user may already be used by the application.

Add Other Assets

If your module should provide other kinds of assets, they can also be injected. Here’s a simple example module injecting a stylesheet through Nuxt’s css array.
And a more advanced one, exposing a folder of assets through Nitro’s publicAssets option:

Use Other Modules

If your module depends on other modules, you can specify them using the moduleDependencies option. This provides a more robust way to handle module dependencies with version constraints and configuration merging:

Use Lifecycle Hooks

Lifecycle hooks allow you to expand almost every aspect of Nuxt. Modules can hook to them programmatically or through the hooks map in their definition.

Module Cleanup

If your module opens, handles, or starts a watcher, you should close it when the Nuxt lifecycle is done. The close hook is available for this.

Add Virtual Files

If you need to add a virtual file that can be imported into the user’s app, you can use the addTemplate utility.
For the server, you should use the addServerTemplate utility instead.

Add Type Declarations

You might also want to add a type declaration to the user’s project (for example, to augment a Nuxt interface or provide a global type of your own). For this, Nuxt provides the addTypeTemplate utility that both writes a template to the disk and adds a reference to it in the generated nuxt.d.ts file.

Next Steps

Now that you’ve learned the common module recipes, explore best practices for building production-ready modules.

Best Practices

Learn how to build performant and maintainable modules