✨OnyxStore - Notification System
🔔 Global Notification System
A reusable, type-safe notification mechanism using Vue’s provide/inject pattern. It allows any component in your Nuxt 3 app to trigger transient notifications (toasts) with ease.
🎯 Features
Supports
success
,error
, andwarning
notificationsAuto-dismiss after 5 seconds
Fully typed with TypeScript
Global availability via inject in any component
Clean, composable logic using Vue Composition API
⚙️ Setup Overview
1. Type Definitions (types/notification.ts
)
types/notification.ts
)export type NotificationType = 'success' | 'error' | 'warning'
export type INotification = {
id: number
message: string
type: NotificationType
}
export type AddNotificationFn = (message: string, type?: NotificationType) => void
2. Provider Setup (layouts/default.vue
or similar)
layouts/default.vue
or similar)<script setup lang="ts">
import { provide, ref } from 'vue'
import type { AddNotificationFn, INotification } from '~/types/notification'
const notifications = ref<INotification[]>([])
const addNotification: AddNotificationFn = (message, type = 'success') => {
const id = Date.now()
notifications.value.push({ id, message, type })
setTimeout(() => {
notifications.value = notifications.value.filter(n => n.id !== id)
}, 5000)
}
provide<AddNotificationFn>('addNotification', addNotification)
</script>
<template>
<!-- Notification container (example) -->
<div class="notification-container">
<Notification v-for="n in notifications" :key="n.id" :data="n" />
</div>
<NuxtLayout />
</template>
3. Inject & Use (pages/login.vue
, etc.)
pages/login.vue
, etc.)<script setup lang="ts">
import { inject } from 'vue'
import type { AddNotificationFn } from '~/types/notification'
const addNotification = inject<AddNotificationFn>('addNotification')
if (!addNotification)
throw new Error('addNotification is not provided!')
function onLoginSuccess() {
addNotification('Logged in successfully!', 'success')
}
function onLoginError() {
addNotification('Login failed. Check credentials and try again.', 'error')
}
</script>
🛠️ Why This Approach
Decoupled
No prop drilling or event buses
Reusable
Works across any layout or page via inject
Type-Safe
Strong typing ensures correct usage
Global Control
Centralized notification list and timeout logic
Scalable
Easy to extend (e.g., configurable timeout)
Vue Best Practice
Follows official provide/inject
guidance (github.com, vuejs.org, scribbr.com, codemag.com)
✅ Guaranteed Availability: inject + runtime check
<script setup lang="ts">
import type { AddNotificationFn } from '~/types/notification'
import { inject } from 'vue'
// 🔍 Attempt to inject
const addNotification = inject<AddNotificationFn>('addNotification')
// ⚠️ If missing, crash early with clear error
if (!addNotification) {
throw new Error(
'⚠ addNotification provider is missing: ensure <Layout> uses provide("addNotification", ...)'
)
}
// ✅ Use it safely
addNotification('Welcome back!', 'success')
</script>
🧩 Why this pattern is professional
Type-safe
inject<AddNotificationFn>
tells TypeScript exactly what to expect
Fail-fast
Throws an error early if provide
is missing, avoiding silent bugs
Clear message
The error explains exactly what’s wrong and how to fix it
Self-documenting
Anyone reading the code knows addNotification
must be provided upstream
🧠 Best Practices
Use this guard in every component that relies on injections for resilience.
The error clearly identifies the missing provider and suggests fixing it by wrapping with the correct Layout.
For production environments, you might log a warning instead of throwing, depending on UX needs.
📌 Example in context (login.vue)
const addNotification = inject<AddNotificationFn>('addNotification')
if (!addNotification) {
throw new Error('something went wrong, Notifications are not available')
}
// Use it like so:
async function handleSubmit() {
try {
// ...login logic
addNotification('Successfully logged in!', 'success')
}
catch (e) {
addNotification('Login failed. Please try again.', 'error')
}
}
🤓 Tips for Maintainers
Clear typing:
AddNotificationFn
guarantees consistent API usageSafe-injection: explicit error thrown if provider is missing
Composable pattern: encapsulated in layout, easily shared
Clean code: no boilerplate in every component—just call
addNotification(...)
🚀 Next Steps (Optional)
Expose notifications: Create a
<Notifications />
component to render the listEnhance UX: Add animations, icons, or manual dismissal buttons
Extend API: Add options like
duration
,title
, or action callbacks
Summary: A lean, robust, and professional notification system using Vue’s modern tooling. Ideal for polished, reusable UX and clear developer experience.
📘 Feel free to copy this to your GitBook under “🔔 Notification System” for perfect documentation.
Last updated