How to create a custom global Nuxt plugin (toast)?
In this article, we'll be building a dynamic global nuxt plugin that is going to be a Toast (snackbar).
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:
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:
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:
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:
<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:
<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)
Then, we import our snackbar component to the default.vue
layout file like:
<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:
plugins: ["~/plugins/notifier.js"],
So, let's try our plugin in index.vue
in the mounted()
hook:
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.