notiwind
notiwind copied to clipboard
use in nuxt
Hi
I want to use notiwind
in nuxtjs
First, I installed it and registered it as a plugin
Second, I added notification components as Notification.vue
file in components
Third, I used it in a page (example notiwind.vue
).
But I encountered the errors that you can see below
Sources:
install:
npm i notiwind -D
Notification.client.js:
// ~/plugins/Notification.client.js
import notifications from 'notiwind'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(notifications)
})
Notification.vue:
<!-- ~/components/Notification.vue -->
<template>
<div>
<NotificationGroup group="sucess-top" position="top">
<div class="z-50 fixed inset-0 flex items-start justify-start p-6 px-4 py-6 pointer-events-none">
<div class="w-full max-w-sm">
<Notification v-slot="{ notifications, close }" enter="ease-out duration-300 transition" enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4" enter-to="translate-y-0 opacity-100 sm:translate-x-0" leave="transition ease-in duration-500" leave-from="opacity-100" leave-to="opacity-0" move="transition duration-500" move-delay="delay-300">
<div v-for="notification in notifications" :key="notification.id" class="w-full max-w-sm mt-4 overflow-hidden bg-white rounded-lg shadow-lg pointer-events-auto ring-1 ring-black ring-opacity-5">
<div class="p-4">
<div class="flex items-start">
<div class="shrink-0">
<svg class="w-6 h-6 text-green-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="mr-3 w-0 flex-1 pt-0.5">
<p class="font-semibold text-gray-800">
{{ notification.title }}
</p>
<p class="text-sm font-semibold text-gray-500">
{{ notification.text }}
</p>
</div>
<div class="flex mr-4 shrink-0">
<button class="inline-flex text-gray-400 bg-white rounded-md hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-400" @click="close(notification.id)">
<span class="sr-only">Close</span>
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
</div>
</div>
</div>
</div>
</Notification>
</div>
</div>
</NotificationGroup>
</div>
</template>
notiwind.vue:
<!-- ~/pages/notiwind.vue -->
<script setup>
import { notify } from 'notiwind';
notify({
group: "sucess-top",
title: "sucess",
text: "Everything is ok",
}, -1);
</script>
<template>
<Notification />
</template>
Errrors (In Terminal):
[Vue warn]: Failed to resolve component: NotificationGroup
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Failed to resolve component: NotificationGroup
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.
[Vue warn]: Component <Anonymous> is missing template or render function.
Errors (In Inspect Console):
Apparently, it does't recognize the NotificationGroup
at all
What's the problem and the solution ?
I had the same problem with nuxt3, using vite + vue 3 works fine.
it's work for me in nuxt3
https://github.com/emmanuelsw/notiwind#typescript
Here is the wrapper component (ToastNotifications.vue
) I am using with Nuxt
<script setup lang="ts">
import { NotificationGroup, Notification } from "notiwind"
import ToastNotification from "@/components/ToastNotification.vue"
</script>
<template>
<!-- global notification region, rendered permanently in document -->
<NotificationGroup>
<div
aria-live="assertive"
class="pointer-events-none fixed z-50 inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6"
>
<div class="flex w-full flex-col items-center space-y-4 sm:items-end">
<!-- notification data is fed through the slot below -->
<Notification
v-slot="{ notifications, close }"
enter="transform ease-out duration-300 transition"
enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
enter-to="translate-y-0 opacity-100 sm:translate-x-0"
leave="transition ease-in duration-100"
leave-from="opacity-100"
leave-to="opacity-0"
>
<ToastNotification
v-for="notification in notifications"
:key="notification.id"
:notification="notification"
:close="close"
/>
</Notification>
</div>
</div>
</NotificationGroup>
</template>
ToastNotification
is my custom component I use to draw the notifications.
This component is included in my primary layout like this:
<script setup>
import SiteHeader from "@/components/SiteHeader.vue"
import ToastNotifications from "@/components/ToastNotifications.vue"
</script>
<template>
<Html class="h-full bg-gray-50" />
<Body class="h-full" />
<div class="min-h-full">
<ToastNotifications />
<SiteHeader />
<main>
<slot />
</main>
</div>
</template>
My nuxt plugin looks like this:
import { defineNuxtPlugin } from "#app"
import Notifications, { notify } from "notiwind"
type NotificationOptions = {
group?: string
title: string
text: string
type?: "info" | "success" | "warn" | "error"
}
// core method, use with $toast("foo")
function notifyFlexible(
info: string | NotificationOptions,
displayFor?: number,
type?: "info" | "success" | "warn" | "error"
) {
if (typeof info === "string") {
notify({ title: info, type }, displayFor)
} else {
notify(info, displayFor)
}
}
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(Notifications)
return {
provide: {
toast: notifyFlexible,
},
}
})
The provide
line includes the name I'm using for access in my components (for me, $toast
). I use it like this:
const { $toast } = useNuxtApp()
$toast("hello world")