modules

Exploring Nuxt Modules

Discover our list of modules to supercharge your Nuxt project, created by the Nuxt team and community.

  • 145+ Modules
  • 89+ Maintainers

Check out modules.nuxtjs.org

modules-servermiddleware-plugins-in-nuxt-js

While developing production-grade applications with Nuxt.js you might find that the framework's core functionality is not enough. Nuxt.js can be extended with configuration options and plugins, but maintaining these customizations across multiple projects is tedious, repetitive and time-consuming. On the other hand, supporting every project's needs out of the box would make Nuxt.js very complex and hard to use.

This is one of the reasons why Nuxt.js provides a higher-order module system that makes it possible to extend the core. Modules are functions that are called sequentially when booting Nuxt.js. The framework waits for each module to finish before continuing. In this way, modules can customize almost any aspect of your project. Thanks to Nuxt.js' modular design (based on webpack's Tapable), modules can easily register hooks for certain entry points like the builder initialization. Modules can also override templates, configure webpack loaders, add CSS libraries, and perform many other useful tasks.

Best of all, Nuxt.js modules can be incorporated into npm packages. This makes it possible to reuse across projects and to share with the community, helping create an ecosystem of high-quality add-ons.

The modules Property

Modules are Nuxt.js extensions which can extend the framework's core functionality and add endless integrations. Once you have installed the modules you can then add them to your nuxt.config.js file under the modules property.

nuxt.config.js
export default {
  modules: [
    // Using package name
    '@nuxtjs/axios',

    // Relative to your project srcDir
    '~/modules/awesome.js',

    // Providing options
    ['@nuxtjs/google-analytics', { ua: 'X1234567' }],

    // Inline definition
    function () {}
  ]
}

Module developers usually provide additionally needed steps and details for usage.

Nuxt.js tries to resolve each item in the modules array using node require path (in the node_modules) and then will resolved from the project srcDir if @ alias is used.

Modules are executed sequentially so the order is important.

Modules should export a function to enhance build/runtime and optionally return a promise until their job is finished. Note that they are imported at runtime so they should be already transpiled if using modern ES6 features.

Write your own Module

Modules are functions. They can be packaged as npm modules or directly included in your project source code.

nuxt.config.js
export default {
  exampleMsg: 'hello',
  modules: [
    // Simple usage
    '~/modules/example',
    // Passing options directly
    ['~/modules/example', { token: '123' }]
  ]
}
modules/example.js
export default function ExampleModule(moduleOptions) {
  console.log(moduleOptions.token) // '123'
  console.log(this.options.exampleMsg) // 'hello'

  this.nuxt.hook('ready', async nuxt => {
    console.log('Nuxt is ready')
  })
}

// REQUIRED if publishing the module as npm package
module.exports.meta = require('./package.json')

1) ModuleOptions

moduleOptions: This is the object passed using the modules array by the user. We can use it to customize it's behavior.

Top level options

Sometimes it is more convenient if we can use top level options while registering modules in nuxt.config.js. This allows us to combine multiple option sources.

nuxt.config.js
export default {
  modules: [['@nuxtjs/axios', { anotherOption: true }]],

  // axios module is aware of this by using `this.options.axios`
  axios: {
    option1,
    option2
  }
}

2) this.options

this.options: You can directly access the Nuxt.js options using this reference. This is the content of the user's nuxt.config.js with all default options assigned to it. It can be used for shared options between modules.

module.js
export default function (moduleOptions) {
  // `options` will contain option1, option2 and anotherOption
  const options = Object.assign({}, this.options.axios, moduleOptions)

  // ...
}

Add a CSS Library

If your module will provide a CSS library, make sure to perform a check if the user already included the library to avoid duplicates, and add an option to disable the CSS library in the module.

module.js
export default function (moduleOptions) {
  if (moduleOptions.fontAwesome !== false) {
    // Add Font Awesome
    this.options.css.push('font-awesome/css/font-awesome.css')
  }
}

Emit assets

We can register webpack plugins to emit assets during build.

module.js
export default function (moduleOptions) {
  const info = 'Built by awesome module - 1.3 alpha on ' + Date.now()

  this.options.build.plugins.push({
    apply(compiler) {
      compiler.plugin('emit', (compilation, cb) => {
        // This will generate `.nuxt/dist/info.txt' with contents of info variable.
        // Source can be buffer too
        compilation.assets['info.txt'] = {
          source: () => info,
          size: () => info.length
        }

        cb()
      })
    }
  })
}

3) this.nuxt

this.nuxt: This is a reference to the current Nuxt.js instance. We can register hooks on certain life cycle events.

  • Ready : Nuxt is ready to work (ModuleContainer and Renderer ready).
nuxt.hook('ready', async nuxt => {
  // Your custom code here
})
  • Error: An unhandled error when calling hooks.
nuxt.hook('error', async error => {
  // Your custom code here
})
  • Close: Nuxt instance is gracefully closing.
nuxt.hook('close', async nuxt => {
  // Your custom code here
})
  • Listen: Nuxt internal server starts listening. (Using nuxt start or nuxt dev)
nuxt.hook('listen', async (server, {host, port})) => {
  // Your custom code here
})

this: Context of modules. All modules will be called within context of the ModuleContainer instance.

Please look into the ModuleContainer class docs for available methods.

Run Tasks on Specific hooks

Your module may need to do things only on specific conditions and not just during Nuxt.js initialization. We can use the powerful Nuxt.js hooks to do tasks on specific events (based on Hable). Nuxt.js will wait for your function if it returns a Promise or is defined as async.

Here are some basic examples:

modules/myModule.js
export default function myModule() {
  this.nuxt.hook('modules:done', moduleContainer => {
    // This will be called when all modules finished loading
  })

  this.nuxt.hook('render:before', renderer => {
    // Called after the renderer was created
  })

  this.nuxt.hook('build:compile', async ({ name, compiler }) => {
    // Called before the compiler (default: webpack) starts
  })

  this.nuxt.hook('generate:before', async generator => {
    // This will be called before Nuxt generates your pages
  })
}

Provide plugins

It is common that modules provide one or more plugins when added. For example bootstrap-vue module would require to register itself into Vue. In such situations we can use the this.addPlugin helper.

plugin.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue/dist/bootstrap-vue.esm'

Vue.use(BootstrapVue)
module.js
import path from 'path'

export default function nuxtBootstrapVue(moduleOptions) {
  // Register `plugin.js` template
  this.addPlugin(path.resolve(__dirname, 'plugin.js'))
}

Template plugins

Registered templates and plugins can leverage lodash templates to conditionally change registered plugins output.

plugin.js
// Set Google Analytics UA
ga('create', '<%= options.ua %>', 'auto')

<% if (options.debug) { %>
// Dev only code
<% } %>
module.js
import path from 'path'

export default function nuxtBootstrapVue(moduleOptions) {
  // Register `plugin.js` template
  this.addPlugin({
    src: path.resolve(__dirname, 'plugin.js'),
    options: {
      // Nuxt will replace `options.ua` with `123` when copying plugin to project
      ua: 123,

      // conditional parts with dev will be stripped from plugin code on production builds
      debug: this.options.dev
    }
  })
}

Register custom webpack loaders

We can do the same as  build.extend  in  nuxt.config.js  using  this.extendBuild.

module.js
export default function (moduleOptions) {
    this.extendBuild((config, { isClient, isServer }) => {
      // `.foo` Loader
      config.module.rules.push({
        test: /\.foo$/,
        use: [...]
      })

      // Customize existing loaders
      // Refer to source code for Nuxt internals:
      // https://github.com/nuxt/nuxt.js/blob/dev/packages/webpack/src/config/base.js
      const barLoader = config.module.rules.find(rule => rule.loader === 'bar-loader')
  })
}

Async Modules

Not all modules will do everything synchronous. For example you may want to develop a module which needs fetching some API or doing asynchronous Operation. For this, Nuxt.js supports async modules which can return a Promise or call a callback.

Use async/await

import fse from 'fs-extra'

export default async function asyncModule() {
  // You can do async work here using `async`/`await`
  const pages = await fse.readJson('./pages.json')
}

Return a Promise

export default function asyncModule($http) {
  return $http
    .get('https://jsonplaceholder.typicode.com/users')
    .then(res => res.data.map(user => '/users/' + user.username))
    .then(routes => {
      // Do something by extending Nuxt routes
    })
}

There are way more hooks and possibilities for modules. Please read the Nuxt Internals to find out more about the nuxt-internal API.

Publishing your module

module.exports.meta: This line is required if you are publishing the module as an npm package. Nuxt internally uses meta to work better with your package.

modules/myModule.js
module.exports.meta = require('./package.json')

buildModules

Some modules are only imported during development and build time. Using buildModules helps to make production startup faster and also significantly decrease the size of your node_modules for production deployments. Please refer to the docs for each module to see if it is recommended to use modules or buildModules.

The usage difference is:

  • Instead of adding to modules inside nuxt.config.js, use buildModules
nuxt.config.js
export default {
  buildModules: ['@nuxtjs/eslint-module']
}
  • Instead of adding to dependencies inside package.json, use devDependencies
yarn add -D @nuxtjs/eslint-module
npm install --save-dev @nuxtjs/eslint-module

If you are a module author, It is highly recommended to suggest to users to install your package as a devDependency and use  buildModules instead of modules for nuxt.config.js.

Your module is a buildModule unless:

  • It is providing a serverMiddleware
  • It has to register a Node.js runtime hook (Like sentry)
  • It is affecting vue-renderer behavior or using a hook from server: or vue-renderer: namespace
  • Anything else that is outside of webpack scope (Hint: plugins and templates are compiled and are in webpack scope)
 

If you are going to offer using buildModules please mention that this feature is only available since Nuxt v2.9. Older users should upgrade Nuxt or use the modules section.

Contributors

Caught a mistake or want to contribute to the documentation? Edit this page on GitHub!