Introduction to Nuxt plugins and modules

Antonis Christofides
Testing nuxt applications
3 min readJun 18, 2021
Not a Nuxt module, but a module nevertheless. Photo by Mark König on Unsplash

I have already explained how we can use MSW to test our Nuxt application’s communication with the backend. I made it work by importing axios and assigning wrapper.vm.$axios = axios.

However, this is actually a bad hack, since @nuxtjs/axios and axios aren’t the same. The former is a Nuxt.js module that wraps axios and offers more functionality on top of it. @nuxtjs/axios and axios happen to have a similar API which enables us to use the latter in place of the former and mock any additional methods we use (such as setToken). But what will we do in other cases where we use a Nuxt.js module that does not wrap something with a similar API? How can we use a Nuxt.js module in our tests? To answer that we need to know some internals of Nuxt.js modules.

A Nuxt.js module is often a wrapper around a Nuxt.js plugin.

A Nuxt.js plugin is often a wrapper around a Vue plugin.

Let’s go through these from the bottom up.

Vue plugins

After the snippet above executes, myVueInstance.$hello will have the value “world”.

A Vue plugin is an object (or module) containing an install() function (the plugin can also be a function itself instead). What Vue.use() does is register the plugin and, if it is not already registered, execute the function.

Vue plugins can be installed (with Vue.use()) either before or after creating the Vue instance.

Nuxt plugins

A Nuxt plugin is a JavaScript file (typically in the plugins directory) whose name is specified in the plugins property in nuxt.config.js. The file may or may not export a function.

Nuxt plugins that do not export a function

Here is an example of a Nuxt plugin that does not export a function:

When Nuxt starts, it merely imports the file.

When a Nuxt plugin merely wraps a Vue plugin, it can simply execute Vue.use(theVuePlugin).

Nuxt plugins that export a function

When Nuxt starts, it will import the file and execute the function, passing it the Nuxt context and the inject function. In this particular case, inject('hello', 'world') will do something similar to the following:

Why not simply write the above instead of exporting a function that receives a callback inject function and calls it? Because the inject function is smart. Depending on Nuxt configuration and environment (e.g. SSR or client), it might decide to add the attribute only to Vue, or only to the context, or also add it to the store, etc. By just executing inject('hello', 'world'), we tell Nuxt to add (“inject”) the $hello attribute to wherever it needs to be added.

Nuxt modules

A Nuxt module is a JavaScript file that exports a function and is specified in the modules property of nuxt.config.js. Nuxt calls the function when it starts.

The difference between a Nuxt module and a Nuxt plugin is that a module runs earlier. Nuxt first loads and executes modules, then creates the Vue instance and the Nuxt context, and then executes Nuxt plugins. As a result, Nuxt modules can do more customization; for example, they can add plugins. I’m still not entirely clear on that, but for the purposes of this post it doesn’t matter, because it is given that we have a module (@nuxtjs/axios) and we need to load it for testing.

How @nuxtjs/axios works

@nuxtjs/axios is a Nuxt module—a .js file that exports a function. Nuxt loads the file and executes the function.

One of the things the function does is execute Nuxt’s addPlugin() method. This is the way to programmatically load a plugin without needing to add it to the plugins property of nuxt.config.js. Since this plugin does not have a name, we will call it “the Nuxt axios plugin”.

So, Nuxt starts. It initializes the @nuxtjs/axios module. The module, among other things, executes Nuxt’s addPlugin(), thus registering the Nuxt axios plugin. Later (after finishing loading all modules, creating the Vue instance and Nuxt context, and possibly doing other initialization work) Nuxt will initialize the Nuxt axios plugin. What the plugin initialization does is create an Axios instance, extend it with some additional methods (such as setToken), and then call Nuxt’s inject to add it as the $axios property of Vue (and of the Nuxt context).

--

--