N
Nuxt5mo ago
Gaurav

Issue: cannot add a custom plugin in nuxt

Hello I was trying to learn custom plugins in nuxt, so I tried to crate a toast plugin which should have 2 functions like getToasts and addSuccessToast but I am not able to use in my nuxt app. this is my plugins/toast.ts file
import {ref} from 'vue'

const toast = {
install(app) {
const toasts = ref<{}[]>([]);
app.config.globalProperties.$toast = {
getToasts: () => toasts,
addSuccess: (msg) => {
toasts.value.push({messsage: msg, type: 'success'});
}
}
}
}

export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(toast);
})
import {ref} from 'vue'

const toast = {
install(app) {
const toasts = ref<{}[]>([]);
app.config.globalProperties.$toast = {
getToasts: () => toasts,
addSuccess: (msg) => {
toasts.value.push({messsage: msg, type: 'success'});
}
}
}
}

export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(toast);
})
and just used $toast in vue component like
<script setup lang="ts">
const {$toast} = useNuxtApp();
onMounted(() => {
console.log($toast)
})
<script setup lang="ts">
const {$toast} = useNuxtApp();
onMounted(() => {
console.log($toast)
})
Can anyone guide me what I am missing?
8 Replies
Kenny
Kenny5mo ago
In your addSuccess function, you have a typo in the property name when you push to the toasts array. You wrote messsage instead of message. This would prevent your toast messages from displaying correctly.
Cue
Cue5mo ago
Am I correct in assuming $toast is undefined in your console log?
Gaurav
GauravOP5mo ago
Yes
Cue
Cue5mo ago
That is because “install” from a Vue plugin alone, as well as any global properties defined within, are not exposed to Nuxt’s plugin scope, rather they are bound to Vue. You’ll essentially want to provide toast from within the Nuxt plugin in order for it to be visible to the Nuxt app context. See https://nuxt.com/docs/guide/directory-structure/plugins#providing-helpers for more details If you wanted to access the global property, you'll want to do it the "Vue" way, not the "Nuxt" way. For example:
const app = getCurrentInstance();
const $toast = app.appContext.config.globalProperties.$toast;
const app = getCurrentInstance();
const $toast = app.appContext.config.globalProperties.$toast;
Which is less than ideal, and you're better off providing a helper via Nuxt for simplicity, or leveraging provide/inject contexts
Gaurav
GauravOP5mo ago
I knew that provide/inject context but I wanted to try some other way o create plugin like below link https://nuxt.com/docs/guide/directory-structure/plugins#vue-plugins But in documentation they showed how to create plugin but not mentioned how to use or maybe I am missing out something.
Nuxt
plugins/ · Nuxt
Nuxt has a plugins system to use Vue plugins and more at the creation of your Vue application.
Cue
Cue5mo ago
Creating Vue plugins but then also making them usable via useNuxtApp composable as per your original question requires additional configuration as outlined above.
Gaurav
GauravOP5mo ago
Understood I should use provide/inject here. thanks @cuebit for help
Cue
Cue5mo ago
If you must compose a Vue native plugin AND provide the plugin API to use within Nuxt context, then you could do the following:
const toast = {
install(app) {
const toasts = ref<{}[]>([]);
app.config.globalProperties.$toast = {
getToasts: () => toasts,
addSuccess: (msg: string) => {
toasts.value.push({ message: msg, type: 'success' });
}
}
}
}

export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(toast)

return {
provide: {
toast: nuxtApp.vueApp.config.globalProperties.$toast
}
}
})
const toast = {
install(app) {
const toasts = ref<{}[]>([]);
app.config.globalProperties.$toast = {
getToasts: () => toasts,
addSuccess: (msg: string) => {
toasts.value.push({ message: msg, type: 'success' });
}
}
}
}

export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(toast)

return {
provide: {
toast: nuxtApp.vueApp.config.globalProperties.$toast
}
}
})

Did you find this page helpful?