Plugins

Nuxt.js allows you to define JavaScript plugins to be run before instantiating the root Vue.js Application. This is especially helpful when using your own libraries or external modules.

It is important to know that in any Vue instance lifecycle, only beforeCreate and created hooks are called both, from client-side and server-side. All other hooks are called only from the client-side.

External Packages

We may want to use external packages/modules in our application (one great example is axios) for making HTTP request for both server and client.

First, we should install it via npm:

  1. npm install --save axios

Then we can use it directly in our page components:

  1. <template>
  2. <h1>{{ title }}</h1>
  3. </template>
  4. <script>
  5. import axios from 'axios'
  6. export default {
  7. async asyncData ({ params }) {
  8. let { data } = await axios.get(`https://my-api/posts/${params.id}`)
  9. return { title: data.title }
  10. }
  11. }
  12. </script>

Vue Plugins

If we want to use Vue plugins, like vue-notifications to display notification in our application, we need to setup the plugin before launching the app.

We create the file plugins/vue-notifications.js:

  1. import Vue from 'vue'
  2. import VueNotifications from 'vue-notifications'
  3. Vue.use(VueNotifications)

Then we add the file path inside the plugins key of our nuxt.config.js:

  1. export default {
  2. plugins: ['~/plugins/vue-notifications']
  3. }

To learn more about the plugins configuration key, check out the plugins api.

ES6 plugins

If the plugin is located in node_modules and exports an ES6 module, you may need to add it to the transpile build option:

  1. module.exports = {
  2. build: {
  3. transpile: ['vue-notifications']
  4. }
  5. }

You can refer to the configuration build docs for more build options.

Inject in $root & context

Sometimes you want to make functions or values available across the 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 $.

Inject into Vue instances

Injecting context into Vue instances works similar to when doing this in standard Vue apps.

plugins/vue-inject.js:

  1. import Vue from 'vue'
  2. Vue.prototype.$myInjectedFunction = (string) => console.log("This is an example", string)

nuxt.config.js:

  1. export default {
  2. plugins: ['~/plugins/vue-inject.js']
  3. }

You can now use the function in all your Vue components.

example-component.vue:

  1. export default {
  2. mounted(){
  3. this.$myInjectedFunction('test')
  4. }
  5. }

Inject into context

Injecting context into Vue instances works similar to when doing this in standard Vue apps.

plugins/ctx-inject.js:

  1. export default ({ app }, inject) => {
  2. // Set the function directly on the context.app object
  3. app.myInjectedFunction = (string) => console.log('Okay, another function', string)
  4. }

nuxt.config.js:

  1. export default {
  2. plugins: ['~/plugins/ctx-inject.js']
  3. }

The function is now available whenever you have access to the context (for example in asyncData and fetch).

ctx-example-component.vue:

  1. export default {
  2. asyncData(context){
  3. context.app.myInjectedFunction('ctx!')
  4. }
  5. }

Combined inject

If you need the function in the context, Vue instances and maybe even in the Vuex store, you can use the inject function, which is the second parameter of the plugins exported function.

Injecting content into Vue instances works similar to when doing this in standard Vue apps. The $ will be prepended automatically to the function.

plugins/combined-inject.js:

  1. export default ({ app }, inject) => {
  2. inject('myInjectedFunction', (string) => console.log('That was easy!', string))
  3. }

nuxt.config.js:

  1. export default {
  2. plugins: ['~/plugins/combined-inject.js']
  3. }

Now the function can be used from context, via this in Vue instances and via this in store actions/mutations.

ctx-example-component.vue:

  1. export default {
  2. mounted(){
  3. this.$myInjectedFunction('works in mounted')
  4. },
  5. asyncData(context){
  6. context.app.$myInjectedFunction('works with context')
  7. }
  8. }

store/index.js:

  1. export const state = () => ({
  2. someValue: ''
  3. })
  4. export const mutations = {
  5. changeSomeValue(state, newValue) {
  6. this.$myInjectedFunction('accessible in mutations')
  7. state.someValue = newValue
  8. }
  9. }
  10. export const actions = {
  11. setSomeValueToWhatever ({ commit }) {
  12. this.$myInjectedFunction('accessible in actions')
  13. const newValue = "whatever"
  14. commit('changeSomeValue', newValue)
  15. }
  16. }

Client-side only

Some plugins might work only in the browser because they lack SSR support.In these situations you can use the mode: client option in plugins to add the plugin only on the client-side.

Example:

nuxt.config.js:

  1. export default {
  2. plugins: [
  3. { src: '~/plugins/vue-notifications', mode: 'client' }
  4. ]
  5. }

plugins/vue-notifications.js:

  1. import Vue from 'vue'
  2. import VueNotifications from 'vue-notifications'
  3. Vue.use(VueNotifications)

In case you need to import some libraries in a plugin only on server-side, you can check if the process.server variable is set to true.

Also, if you need to know if you are inside a generated app (via nuxt generate), you can check if process.static is set to true. This is only the case during and after the generation.

You can also combine both options to hit the spot when a page is being server-rendered by nuxt generate before being saved (process.static && process.server).

Note: Since Nuxt.js 2.4, mode has been introduced as option of plugins to specify plugin type, possible value are: client or server. ssr: false will be adapted to mode: 'client' and deprecated in next major release.

Example:

nuxt.config.js:

  1. export default {
  2. plugins: [
  3. { src: '~/plugins/both-sides.js' },
  4. { src: '~/plugins/client-only.js', mode: 'client' },
  5. { src: '~/plugins/server-only.js', mode: 'server' }
  6. ]
  7. }

Name conventional plugin

If plugin is assumed to be run only in client or server side, .client.js or .server.js can be applied as extension of plugin file, the file will be automatically included in corresponding side.

Example:

nuxt.config.js:

  1. export default {
  2. plugins: [
  3. '~/plugins/foo.client.js', // only in client side
  4. '~/plugins/bar.server.js', // only in server side
  5. '~/plugins/baz.js' // both client & server
  6. ]
  7. }