How to create a custom global Nuxt plugin (toast)?
Tags: vue, javascript, css, tutorial
Published: 2021-02-13 21:28:15

In this article, we'll be building a dynamic global nuxt plugin that is going to be a Toast (snackbar).

**Prerequisites**:
* Vue
* Vuex
* Nuxt

**So**, Let's start by creating a Nuxt app using npx:
```javascript
npx create-nuxt-app nuxt-toast
```

Go with the steps and in the UI framework option choose Vuetify.js as we're going to be using it in this tutorial but, if you don't want to use Vuetify you can change the UI framework you like or even without a UI framework.

**Create** a file named `snackbar.js` in the store folder to use Vuex then write:
```javascript
export const state = () => ({
  content: "",
  color: ""
});

export const mutations = {
  showMessage(state, payload) {
    state.content = payload.content;
    state.color = payload.color;
  }
};

```

We export the state function that has content and color values for the toast and the mutations object that contains the show message function that sets the state values to the payload values.

**Then**, Create a file named `notifier.js` in the plugins folder and write:
```javascript
export default ({ app, store }, inject) => {
  inject("notifier", {
    showMessage({ content = "", color = "" }) {
      store.commit("snackbar/showMessage", { content, color });
    }
  });
};

```

Here, we are exporting the plugin's function that we're passing two parameters which are app and store object because we will use vuex store to set the payload that sets the state values to our desired content and color then, there's the second parameter inject that will inject our notifier function to become a global nuxt function to be called like `this.$notifier`.

**Then**, create a file named `Snackbar.vue` in the components folder and write the vue template:
```vue
<template>
  <v-snackbar v-model="show" :color="color">
    {{ message }}
    <template v-slot:action="{ attrs }">
      <v-btn color="white" text v-bind="attrs" @click="show = false">
        Close
      </v-btn>
    </template>
  </v-snackbar>
</template>
```
As you see we used vuetify's snackbar component for our toast as I said if you don't want to use vuetify create your custom component as you want.

**Then**, write below the template the script tag:
```vue
<script>
export default {
  data() {
    return {
      show: false,
      message: "",
      color: ""
    };
  },
  created() {
    this.$store.subscribe((mutation, state) => {
      if (mutation.type === "snackbar/showMessage") {
        this.message = state.snackbar.content;
        this.color = state.snackbar.color;
        this.show = true;
      }
    });
  }
};
</script>

```
Here, we're defining the data(showSnackbar, message, color), In the `created()` hook we use the `this.$store.subscribe` function to subscribe to store mutations as we get mutation and state params so we check if the mutation type is equal to "snackbar/showMessage" (snackbar.js file and showMessage function at our store).

([for more info about store subscribe](https://vuex.vuejs.org/api/#subscribe))

**Then**, we import our snackbar component to the `default.vue` layout file like:
```vue
<template>
  <v-app>
    <v-main>
      <v-container>
        <nuxt />
      </v-container>
    </v-main>
    <Snackbar></Snackbar>
  </v-app>
</template>

<script>
import Snackbar from "~/components/Snackbar";

export default {
  components: {
    Snackbar
  }
};
</script>

```

**Finally**, the last thing we do to make the plugin work is to define our plugin in the `nuxt.config.js` file like this:
```json
  plugins: ["~/plugins/notifier.js"],
```

**So**, let's try our plugin in `index.vue` in the `mounted()` hook: 
```javascript
mounted() {
  this.$notifier.showMessage({
    content: "YAY Our Plugin worked Successfully!",
    color: "success"
  });
}
```
You can use it for HTTP request responses or however you want to use it.

I hope you enjoyed the article and found it useful!

***

[**If you like this article you can subscribe to my newsletter**](https://amrelmohamady.hashnode.dev/)

You can also buy me a coffee that would help :)
<a href="https://www.buymeacoffee.com/amrelmohamady" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>