The plugins
directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use Vue.use()
, you should create a file in plugins/
and add its path to plugins
in nuxt.config.js
.
You may want to use external packages/modules in your application (one great example is axios) for making HTTP requests for both server and client.
First, install it via npm or Yarn.
npm install @nuxtjs/axios
You can configure for example the axios interceptors to react on possible errors from your API calls across the application. In this example we redirect the user to a custom error page called sorry when we get a 500 status error from our API.
plugins/axios.js
export default function ({ $axios, redirect }) {
$axios.onError(error => {
if (error.response.status === 500) {
redirect('/sorry')
}
})
}
Last but not least, add the module and the newly created plugin to the project configuration.
nuxt.config.js
module.exports = {
modules: ['@nuxtjs/axios'],
plugins: ['~/plugins/axios.js']
}
Then we can use it directly in your page components:
pages/index.vue
<template>
<h1>{{ post.title }}</h1>
</template>
<script>
export default {
async asyncData ({ $axios, params }) {
const post = await $axios.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
return { post }
}
}
</script>
Another way to use axios
without installing the module is by importing axios
direct in the <script>
tag.
pages/index.vue
import axios from 'axios'
export default {
async asyncData ({ params }) {
const { data: post } = await axios.get(`https://api.nuxtjs.dev/posts/${params.id}`)
return { post }
}
}
If you get an Cannot use import statement outside a module error, you may need to add your package to the build
> transpile
option in nuxt.config.js
for webpack loader to make your plugin available.
nuxt.config.js
Vue Plugins
First we need to install it
yarn add v-tooltip
npm install v-tooltip
Then we create the file plugins/vue-tooltip.js
plugins/vue-tooltip.js
import Vue from 'vue'
import VTooltip from 'v-tooltip'
Vue.use(VTooltip)
Then we add the file path inside the plugins
key of our nuxt.config.js
. The plugins property lets you add Vue.js plugins easily to your main application. All the paths defined in the plugins
property will be imported before initializing the main application.
nuxt.config.js
export default {
plugins: ['~/plugins/vue-tooltip.js']
}
If the plugin is located in node_modules
and exports an ES6 module, you may need to add it to the transpile
build option:
nuxt.config.js
module.exports = {
build: {
transpile: ['vue-tooltip']
}
}
You can refer to the configuration build docs for more build options.
Some plugins might work only in the browser because they lack SSR support.
If a plugin is assumed to be run only on client or server side, .client.js
or .server.js
can be applied as an extension of the plugin file. The file will be automatically included only on the respective (client or server) side.
nuxt.config.js
You can also use the object syntax with the mode
property ('client'
or 'server'
) in plugins
.
nuxt.config.js
export default {
plugins: [
{ src: '~/plugins/both-sides.js' },
{ src: '~/plugins/client-only.js', mode: 'client' }, // only on client side
{ src: '~/plugins/server-only.js', mode: 'server' } // only on server side
]
}
Inject in $root
& context
Sometimes you want to make functions or values available across your app. You can inject those variables into Vue instances (client side), the context (server side) and even in the Vuex store. It is a convention to prefix those functions with a $
.
It is important to know that in any Vue instance lifecycle, only beforeCreate
and hooks are called both, from client-side and server-side. All other hooks are called only from the client-side.
plugins/hello.js
export default ({ app }, inject) => {
// Inject $hello(msg) in Vue, context and store.
inject('hello', msg => console.log(`Hello ${msg}!`))
nuxt.config.js
export default {
plugins: ['~/plugins/hello.js']
}
Now $hello
service can be accessed from context
and this
in pages, components, plugins, and store actions.
example-component.vue
export default {
mounted() {
this.$hello('mounted')
// will console.log 'Hello mounted!'
},
asyncData({ app, $hello }) {
$hello('asyncData')
// If using Nuxt <= 2.12, use 👇
app.$hello('asyncData')
}
}
store/index.js
export const state = () => ({
someValue: ''
})
export const actions = {
setSomeValueToWhatever({ commit }) {
this.$hello('store action')
const newValue = 'whatever'
commit('changeSomeValue', newValue)
}
}
Don’t use Vue.use()
, Vue.component()
, and globally, don’t plug anything in Vue inside this function, dedicated to Nuxt injection. It will cause memory leak on server-side.
You may want to extend plugins or change the plugins order created by Nuxt.js. This function accepts an array of objects and should return an array of plugin objects.
Example of changing plugins order:
nuxt.config.js
Global mixins
Global mixins can be easily added with Nuxt plugins but can cause trouble and memory leaks when not handled correctly. Whenever you add a global mixin to your application, you should use a flag to avoid registering it multiple times:
plugins/my-mixin-plugin.js
import Vue from "vue"
// Make sure to pick a unique name for the flag
// so it won't conflict with any other mixin.
if (!Vue.__my_mixin__) {
Vue.__my_mixin__ = true
Vue.mixin({ ... }) // Set up your mixin then