{"id":26417327,"url":"https://github.com/awalhadi/notifyx","last_synced_at":"2026-04-01T23:02:25.017Z","repository":{"id":281893714,"uuid":"946789748","full_name":"awalhadi/notifyx","owner":"awalhadi","description":"Modern JavaScript Toast Notification Library for React, Vue, Angular \u0026 Vanilla JS","archived":false,"fork":false,"pushed_at":"2025-12-12T05:25:42.000Z","size":345,"stargazers_count":10,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-28T00:58:06.625Z","etag":null,"topics":["notifier","notify","notifyjs","notifyx","toast","toaster","toastify","toastr"],"latest_commit_sha":null,"homepage":"https://www.notifyx.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awalhadi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-11T17:17:14.000Z","updated_at":"2026-03-24T02:45:05.000Z","dependencies_parsed_at":"2025-07-22T02:11:13.955Z","dependency_job_id":"14c2e2d9-c953-427e-9d26-1f5df4b6abe8","html_url":"https://github.com/awalhadi/notifyx","commit_stats":null,"previous_names":["awalhadi/notifyx"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/awalhadi/notifyx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalhadi%2Fnotifyx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalhadi%2Fnotifyx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalhadi%2Fnotifyx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalhadi%2Fnotifyx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awalhadi","download_url":"https://codeload.github.com/awalhadi/notifyx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalhadi%2Fnotifyx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["notifier","notify","notifyjs","notifyx","toast","toaster","toastify","toastr"],"created_at":"2025-03-18T01:01:50.518Z","updated_at":"2026-04-01T23:02:25.010Z","avatar_url":"https://github.com/awalhadi.png","language":"TypeScript","readme":"\u003cdiv align=\"center\"\u003e\n\n# 🚀 NotifyX\n\n### Beautiful Toast Notifications for Modern Web Apps\n\n**A lightweight, framework-agnostic notification library with zero dependencies**\n\n[![npm version](https://img.shields.io/npm/v/notifyx?color=success\u0026style=flat-square)](https://www.npmjs.com/package/notifyx)\n[![npm downloads](https://img.shields.io/npm/dm/notifyx?style=flat-square)](https://www.npmjs.com/package/notifyx)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/notifyx?style=flat-square)](https://bundlephobia.com/package/notifyx)\n[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square)](https://www.typescriptlang.org/)\n[![license](https://img.shields.io/npm/l/notifyx?style=flat-square)](LICENSE)\n\n[Demo](https://github.com/awalhadi/notifyx) • [Installation](#-installation) • [Quick Start](#-quick-start) • [Examples](#-real-world-examples) • [API](#-complete-api-reference)\n\n\u003c/div\u003e\n\n---\n\n## ✨ Why NotifyX?\n\n**NotifyX** is designed for developers who want beautiful, accessible toast notifications without the bloat. Here's what makes it special:\n\n- 🎯 **Universal** - Works seamlessly with React, Next.js, Vue, Angular, Svelte, Laravel, or plain JavaScript\n- ⚡ **Tiny Bundle** - Less than 3KB gzipped with zero runtime dependencies\n- 🎨 **Beautiful by Default** - Gorgeous Tailwind CSS styles with smooth animations\n- 🌙 **Dark Mode** - Automatic dark mode detection and beautiful theming\n- 📘 **TypeScript First** - Built with TypeScript, includes complete type definitions\n- ♿ **Accessible** - WCAG compliant with ARIA attributes and keyboard support\n- 🎛️ **Flexible** - Four toast types, four positions, customizable duration, and easy styling\n- 🚀 **Production Ready** - Battle-tested with comprehensive error handling\n\n## 📦 Installation\n\n```bash\n# npm\nnpm install notifyx\n\n# yarn\nyarn add notifyx\n\n# pnpm\npnpm add notifyx\n\n# bun\nbun add notifyx\n```\n\n---\n\n## 📦 Installation\n\nChoose your favorite package manager:\n\n```bash\n# npm\nnpm install notifyx\n\n# yarn\nyarn add notifyx\n\n# pnpm\npnpm add notifyx\n\n# bun\nbun add notifyx\n```\n\n**Or use via CDN** (for vanilla JavaScript projects):\n\n```html\n\u003c!-- CSS --\u003e\n\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.css\" /\u003e\n\n\u003c!-- JavaScript --\u003e\n\u003cscript src=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.js\"\u003e\u003c/script\u003e\n```\n\n---\n\n## 🚀 Quick Start\n\n### Your First Notification in 30 Seconds\n\n**Step 1:** Import NotifyX and its styles\n\n```javascript\nimport NotifyX from 'notifyx';\nimport 'notifyx/style.css';\n```\n\n**Step 2:** Show your first notification\n\n```javascript\nNotifyX.success('Welcome to NotifyX! 🎉');\n```\n\nThat's it! You now have beautiful toast notifications.\n\n---\n\n## 🎯 Four Types of Notifications\n\nNotifyX provides four notification types for different scenarios:\n\n```javascript\n// ✅ Success - For positive outcomes\nNotifyX.success('Payment completed successfully!');\n\n// ❌ Error - For errors and failures\nNotifyX.error('Failed to upload file. Please try again.');\n\n// ⚠️ Warning - For important alerts\nNotifyX.warning('Your session will expire in 5 minutes.');\n\n// ℹ️ Info - For general information\nNotifyX.info('New features are now available!');\n```\n\n### Visual Guide\n\n| Type | When to Use | Example |\n|------|-------------|---------|\n| **Success** | Successful operations, confirmations | \"Settings saved\", \"File uploaded\" |\n| **Error** | Errors, failures, validation issues | \"Network error\", \"Invalid input\" |\n| **Warning** | Important warnings, cautions | \"Low storage\", \"Unsaved changes\" |\n| **Info** | General information, updates | \"New message\", \"System update\" |\n\n---\n\n## 📍 Position Your Notifications\n\nPlace notifications in any corner of the screen:\n\n```javascript\n// Top positions (default: top-right)\nNotifyX.info('Top Right Position', { position: 'top-right' });\nNotifyX.info('Top Left Position', { position: 'top-left' });\n\n// Bottom positions\nNotifyX.info('Bottom Right Position', { position: 'bottom-right' });\nNotifyX.info('Bottom Left Position', { position: 'bottom-left' });\n```\n\n**Pro Tip:** Use constants for better code maintainability:\n\n```javascript\nimport NotifyX, { POSITIONS } from 'notifyx';\n\nNotifyX.success('Saved!', { position: POSITIONS.BOTTOM_RIGHT });\nNotifyX.error('Error!', { position: POSITIONS.TOP_LEFT });\n```\n\n---\n\n## ⏱️ Control Duration\n\nCustomize how long notifications stay visible:\n\n```javascript\n// Quick notification (1 second)\nNotifyX.success('Copied!', { duration: 1000 });\n\n// Standard notification (3 seconds - default)\nNotifyX.info('Processing your request...');\n\n// Longer notification (10 seconds)\nNotifyX.warning('Please read this carefully!', { duration: 10000 });\n\n// Persistent notification (stays until manually dismissed)\nNotifyX.error('Critical error - action required', { duration: 0 });\n```\n\n**Duration Quick Reference:**\n- `duration: 1000` - 1 second (quick actions)\n- `duration: 3000` - 3 seconds (default)\n- `duration: 5000` - 5 seconds (important info)\n- `duration: 0` - Persistent (manual dismiss only)\n\n---\n\n## 🎨 Advanced Configuration\n\nFor complete control, use the `show()` method with custom options:\n\n```javascript\nNotifyX.show({\n  message: 'User profile updated successfully!',\n  type: 'success',\n  position: 'bottom-right',\n  duration: 5000,\n  dismissible: true,\n  onClose: () =\u003e {\n    console.log('Notification was closed');\n    // Perform cleanup or tracking\n  }\n});\n```\n\n### All Available Options\n\n```typescript\n{\n  message: string;       // The notification message (required)\n  type: string;          // 'success' | 'error' | 'warning' | 'info'\n  position: string;      // 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\n  duration: number;      // Milliseconds (0 = persistent)\n  dismissible: boolean;  // Show close button (default: true)\n  onClose: () =\u003e void;   // Callback when notification closes\n  maxToasts: number;     // Maximum simultaneous toasts (default: 5)\n}\n```\n\n---\n\n## 💼 Real-World Examples\n\n### Example 1: Form Validation\n\n```javascript\nfunction handleFormSubmit(event) {\n  event.preventDefault();\n  \n  const email = document.getElementById('email').value;\n  const password = document.getElementById('password').value;\n  \n  // Validate email\n  if (!email || !email.includes('@')) {\n    NotifyX.error('Please enter a valid email address');\n    return;\n  }\n  \n  // Validate password\n  if (!password || password.length \u003c 8) {\n    NotifyX.error('Password must be at least 8 characters');\n    return;\n  }\n  \n  // Success\n  NotifyX.success('Account created successfully! 🎉');\n}\n```\n\n### Example 2: API Calls with Async/Await\n\n```javascript\nasync function fetchUserData(userId) {\n  try {\n    // Show loading state\n    NotifyX.info('Loading user data...', { duration: 0 });\n    \n    const response = await fetch(`/api/users/${userId}`);\n    \n    if (!response.ok) {\n      throw new Error('Failed to fetch user');\n    }\n    \n    const data = await response.json();\n    \n    // Clear loading and show success\n    NotifyX.clear();\n    NotifyX.success(`Welcome back, ${data.name}!`);\n    \n    return data;\n  } catch (error) {\n    NotifyX.clear();\n    NotifyX.error('Unable to load user data. Please try again.');\n    console.error(error);\n  }\n}\n```\n\n### Example 3: Copy to Clipboard\n\n```javascript\nfunction copyToClipboard(text) {\n  navigator.clipboard.writeText(text)\n    .then(() =\u003e {\n      NotifyX.success('Copied to clipboard!', { \n        duration: 2000,\n        position: 'bottom-right' \n      });\n    })\n    .catch(() =\u003e {\n      NotifyX.error('Failed to copy. Please try again.');\n    });\n}\n\n// Usage\ndocument.querySelector('#copy-btn').addEventListener('click', () =\u003e {\n  copyToClipboard('Hello, NotifyX!');\n});\n```\n\n### Example 4: File Upload Progress\n\n```javascript\nasync function uploadFile(file) {\n  // Show initial notification\n  NotifyX.info('Uploading file...', { duration: 0 });\n  \n  const formData = new FormData();\n  formData.append('file', file);\n  \n  try {\n    const response = await fetch('/api/upload', {\n      method: 'POST',\n      body: formData\n    });\n    \n    if (response.ok) {\n      NotifyX.clear();\n      NotifyX.success(`${file.name} uploaded successfully!`);\n    } else {\n      throw new Error('Upload failed');\n    }\n  } catch (error) {\n    NotifyX.clear();\n    NotifyX.error('Upload failed. Please try again.');\n  }\n}\n```\n\n### Example 5: Delete Confirmation with Callback\n\n```javascript\nfunction deleteItem(itemId, itemName) {\n  if (confirm(`Are you sure you want to delete \"${itemName}\"?`)) {\n    NotifyX.info('Deleting...', { duration: 0 });\n    \n    fetch(`/api/items/${itemId}`, { method: 'DELETE' })\n      .then(() =\u003e {\n        NotifyX.clear();\n        NotifyX.success('Item deleted successfully', {\n          duration: 3000,\n          onClose: () =\u003e {\n            // Refresh the list after notification closes\n            refreshItemList();\n          }\n        });\n      })\n      .catch(() =\u003e {\n        NotifyX.clear();\n        NotifyX.error('Failed to delete item');\n      });\n  }\n}\n```\n\n### Example 6: Multiple Notifications Management\n\n```javascript\nfunction performBatchOperation(items) {\n  let successCount = 0;\n  let errorCount = 0;\n  \n  items.forEach(async (item, index) =\u003e {\n    try {\n      await processItem(item);\n      successCount++;\n      \n      // Show progress\n      NotifyX.info(`Processing: ${index + 1} of ${items.length}`);\n    } catch (error) {\n      errorCount++;\n    }\n  });\n  \n  // Show final summary\n  setTimeout(() =\u003e {\n    NotifyX.clear(); // Clear progress notifications\n    \n    if (errorCount === 0) {\n      NotifyX.success(`All ${successCount} items processed successfully!`);\n    } else {\n      NotifyX.warning(`Completed with ${successCount} success, ${errorCount} errors`);\n    }\n  }, 2000);\n}\n```\n\n---\n\n## 🌐 Framework Integration Guide\n\n### React Toast Notifications\n\n#### Basic React Example\n\n```jsx\nimport React from 'react';\nimport NotifyX from 'notifyx';\nimport 'notifyx/style.css';\n\nfunction App() {\n  const handleClick = () =\u003e {\n    NotifyX.success('Button clicked!');\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={handleClick}\u003eShow Notification\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default App;\n```\n\n#### React with Custom Hook\n\n```jsx\nimport { useCallback } from 'react';\nimport NotifyX from 'notifyx';\nimport 'notifyx/style.css';\n\n// Custom hook for notifications\nfunction useNotification() {\n  const showSuccess = useCallback((message) =\u003e {\n    NotifyX.success(message);\n  }, []);\n\n  const showError = useCallback((message) =\u003e {\n    NotifyX.error(message);\n  }, []);\n\n  const showWarning = useCallback((message) =\u003e {\n    NotifyX.warning(message);\n  }, []);\n\n  const showInfo = useCallback((message) =\u003e {\n    NotifyX.info(message);\n  }, []);\n\n  return { showSuccess, showError, showWarning, showInfo };\n}\n\n// Usage in component\nfunction MyComponent() {\n  const notify = useNotification();\n\n  const handleSave = () =\u003e {\n    notify.showSuccess('Changes saved!');\n  };\n\n  return \u003cbutton onClick={handleSave}\u003eSave\u003c/button\u003e;\n}\n```\n\n---\n\n### Next.js Toast Notifications\n\n#### Next.js 13+ App Router (Recommended)\n\n**Step 1:** Create a client component for notifications\n\n```tsx\n// app/components/ToastButton.tsx\n'use client';\n\nimport NotifyX from 'notifyx';\nimport 'notifyx/style.css';\n\nexport default function ToastButton() {\n  return (\n    \u003cbutton \n      onClick={() =\u003e NotifyX.success('Hello from Next.js!')}\n      className=\"px-4 py-2 bg-blue-500 text-white rounded\"\n    \u003e\n      Show Notification\n    \u003c/button\u003e\n  );\n}\n```\n\n**Step 2:** Import styles in your root layout\n\n```tsx\n// app/layout.tsx\nimport 'notifyx/style.css';\nimport './globals.css';\n\nexport default function RootLayout({ \n  children \n}: { \n  children: React.ReactNode \n}) {\n  return (\n    \u003chtml lang=\"en\"\u003e\n      \u003cbody\u003e{children}\u003c/body\u003e\n    \u003c/html\u003e\n  );\n}\n```\n\n**Step 3:** Use the component in your pages\n\n```tsx\n// app/page.tsx\nimport ToastButton from './components/ToastButton';\n\nexport default function Home() {\n  return (\n    \u003cmain\u003e\n      \u003ch1\u003eMy Next.js App\u003c/h1\u003e\n      \u003cToastButton /\u003e\n    \u003c/main\u003e\n  );\n}\n```\n\n#### Next.js Pages Router\n\n```tsx\n// pages/_app.tsx\nimport type { AppProps } from 'next/app';\nimport 'notifyx/style.css';\nimport '../styles/globals.css';\n\nexport default function App({ Component, pageProps }: AppProps) {\n  return \u003cComponent {...pageProps} /\u003e;\n}\n```\n\n```tsx\n// pages/index.tsx\nimport NotifyX from 'notifyx';\n\nexport default function Home() {\n  return (\n    \u003cbutton onClick={() =\u003e NotifyX.success('Next.js Pages Router!')}\u003e\n      Show Toast\n    \u003c/button\u003e\n  );\n}\n```\n\n#### Next.js API Route Integration\n\n```typescript\n// app/api/save/route.ts\nimport { NextResponse } from 'next/server';\n\nexport async function POST(request: Request) {\n  try {\n    const data = await request.json();\n    // Process data...\n    \n    return NextResponse.json({ \n      success: true, \n      message: 'Data saved successfully!' \n    });\n  } catch (error) {\n    return NextResponse.json({ \n      success: false, \n      message: 'Failed to save data' \n    }, { status: 500 });\n  }\n}\n```\n\n```tsx\n// Client component using the API\n'use client';\n\nimport NotifyX from 'notifyx';\n\nexport default function SaveButton() {\n  const handleSave = async () =\u003e {\n    try {\n      const response = await fetch('/api/save', {\n        method: 'POST',\n        body: JSON.stringify({ data: 'example' })\n      });\n      \n      const result = await response.json();\n      \n      if (result.success) {\n        NotifyX.success(result.message);\n      } else {\n        NotifyX.error(result.message);\n      }\n    } catch (error) {\n      NotifyX.error('Network error occurred');\n    }\n  };\n\n  return \u003cbutton onClick={handleSave}\u003eSave Data\u003c/button\u003e;\n}\n```\n\n---\n\n### Vue Toast Notifications\n\n#### Vue 3 Composition API\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv\u003e\n    \u003cbutton @click=\"showSuccess\"\u003eSuccess\u003c/button\u003e\n    \u003cbutton @click=\"showError\"\u003eError\u003c/button\u003e\n    \u003cbutton @click=\"showWarning\"\u003eWarning\u003c/button\u003e\n    \u003cbutton @click=\"showInfo\"\u003eInfo\u003c/button\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport NotifyX from 'notifyx';\nimport 'notifyx/style.css';\n\nconst showSuccess = () =\u003e {\n  NotifyX.success('Operation successful!');\n};\n\nconst showError = () =\u003e {\n  NotifyX.error('Something went wrong!');\n};\n\nconst showWarning = () =\u003e {\n  NotifyX.warning('Please be careful!');\n};\n\nconst showInfo = () =\u003e {\n  NotifyX.info('Here is some information.');\n};\n\u003c/script\u003e\n```\n\n#### Vue 3 with Composable\n\n```typescript\n// composables/useNotify.ts\nimport NotifyX from 'notifyx';\n\nexport function useNotify() {\n  const success = (message: string) =\u003e NotifyX.success(message);\n  const error = (message: string) =\u003e NotifyX.error(message);\n  const warning = (message: string) =\u003e NotifyX.warning(message);\n  const info = (message: string) =\u003e NotifyX.info(message);\n\n  return { success, error, warning, info };\n}\n```\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton @click=\"notify.success('Saved successfully!')\"\u003eSave\u003c/button\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport { useNotify } from '@/composables/useNotify';\n\nconst notify = useNotify();\n\u003c/script\u003e\n```\n\n---\n\n### Angular Toast Notifications\n\n#### Basic Angular Integration\n\n```typescript\n// app.component.ts\nimport { Component } from '@angular/core';\nimport NotifyX from 'notifyx';\n\n@Component({\n  selector: 'app-root',\n  template: `\n    \u003cbutton (click)=\"showNotification()\"\u003eShow Toast\u003c/button\u003e\n  `,\n  styles: []\n})\nexport class AppComponent {\n  showNotification() {\n    NotifyX.success('Hello from Angular!');\n  }\n}\n```\n\n#### Import styles in angular.json\n\n```json\n{\n  \"styles\": [\n    \"src/styles.css\",\n    \"node_modules/notifyx/style.css\"\n  ]\n}\n```\n\n#### Angular Service for Notifications\n\n```typescript\n// services/notification.service.ts\nimport { Injectable } from '@angular/core';\nimport NotifyX from 'notifyx';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class NotificationService {\n  success(message: string) {\n    NotifyX.success(message);\n  }\n\n  error(message: string) {\n    NotifyX.error(message);\n  }\n\n  warning(message: string) {\n    NotifyX.warning(message);\n  }\n\n  info(message: string) {\n    NotifyX.info(message);\n  }\n\n  clear() {\n    NotifyX.clear();\n  }\n}\n```\n\n```typescript\n// app.component.ts\nimport { Component } from '@angular/core';\nimport { NotificationService } from './services/notification.service';\n\n@Component({\n  selector: 'app-root',\n  template: `\u003cbutton (click)=\"save()\"\u003eSave\u003c/button\u003e`\n})\nexport class AppComponent {\n  constructor(private notification: NotificationService) {}\n\n  save() {\n    this.notification.success('Saved successfully!');\n  }\n}\n```\n\n---\n\n### Laravel Toast Notifications\n\n#### Option 1: Laravel with Vite (Recommended)\n\n**Step 1:** Install NotifyX\n\n```bash\nnpm install notifyx\n```\n\n**Step 2:** Import in your main JavaScript file\n\n```javascript\n// resources/js/app.js\nimport NotifyX from 'notifyx';\nimport 'notifyx/style.css';\n\n// Make NotifyX globally available\nwindow.NotifyX = NotifyX;\n\n// Example helper function\nwindow.showToast = (message, type = 'info') =\u003e {\n  NotifyX[type](message);\n};\n```\n\n**Step 3:** Use in Blade templates\n\n```blade\n{{-- resources/views/layouts/app.blade.php --}}\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003ctitle\u003eMy Laravel App\u003c/title\u003e\n    @vite(['resources/css/app.css', 'resources/js/app.js'])\n\u003c/head\u003e\n\u003cbody\u003e\n    @yield('content')\n    \n    {{-- Flash messages --}}\n    @if(session('success'))\n        \u003cscript\u003e\n            document.addEventListener('DOMContentLoaded', () =\u003e {\n                NotifyX.success('{{ session('success') }}');\n            });\n        \u003c/script\u003e\n    @endif\n    \n    @if(session('error'))\n        \u003cscript\u003e\n            document.addEventListener('DOMContentLoaded', () =\u003e {\n                NotifyX.error('{{ session('error') }}');\n            });\n        \u003c/script\u003e\n    @endif\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n```blade\n{{-- resources/views/posts/create.blade.php --}}\n@extends('layouts.app')\n\n@section('content')\n\u003cform action=\"/posts\" method=\"POST\" onsubmit=\"handleSubmit(event)\"\u003e\n    @csrf\n    \u003cinput type=\"text\" name=\"title\" required\u003e\n    \u003cbutton type=\"submit\"\u003eCreate Post\u003c/button\u003e\n\u003c/form\u003e\n\n\u003cscript\u003e\nfunction handleSubmit(event) {\n    // Client-side notification\n    showToast('Creating post...', 'info');\n}\n\u003c/script\u003e\n@endsection\n```\n\n#### Option 2: Laravel with CDN\n\n```blade\n{{-- resources/views/layouts/app.blade.php --}}\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003ctitle\u003eMy Laravel App\u003c/title\u003e\n    \u003clink rel=\"stylesheet\" href=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    @yield('content')\n    \n    \u003cscript src=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.js\"\u003e\u003c/script\u003e\n    \n    {{-- Laravel flash messages --}}\n    @if(session('success'))\n        \u003cscript\u003eNotifyX.success('{{ session('success') }}');\u003c/script\u003e\n    @endif\n    \n    @if(session('error'))\n        \u003cscript\u003eNotifyX.error('{{ session('error') }}');\u003c/script\u003e\n    @endif\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### Laravel Controller with Flash Messages\n\n```php\n// app/Http/Controllers/PostController.php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse Illuminate\\Http\\Request;\n\nclass PostController extends Controller\n{\n    public function store(Request $request)\n    {\n        $request-\u003evalidate([\n            'title' =\u003e 'required|max:255',\n            'content' =\u003e 'required',\n        ]);\n\n        // Save post...\n        \n        return redirect('/posts')\n            -\u003ewith('success', 'Post created successfully!');\n    }\n\n    public function destroy($id)\n    {\n        try {\n            // Delete post...\n            \n            return redirect('/posts')\n                -\u003ewith('success', 'Post deleted successfully!');\n        } catch (\\Exception $e) {\n            return redirect('/posts')\n                -\u003ewith('error', 'Failed to delete post.');\n        }\n    }\n}\n```\n\n---\n\n### Vanilla JavaScript / HTML (CDN)\n\nPerfect for static sites, WordPress, or any HTML page:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eNotifyX Demo\u003c/title\u003e\n    \n    \u003c!-- NotifyX CSS --\u003e\n    \u003clink rel=\"stylesheet\" href=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003eNotifyX Vanilla JS Demo\u003c/h1\u003e\n    \n    \u003cbutton onclick=\"NotifyX.success('Success!')\"\u003eSuccess\u003c/button\u003e\n    \u003cbutton onclick=\"NotifyX.error('Error!')\"\u003eError\u003c/button\u003e\n    \u003cbutton onclick=\"NotifyX.warning('Warning!')\"\u003eWarning\u003c/button\u003e\n    \u003cbutton onclick=\"NotifyX.info('Info!')\"\u003eInfo\u003c/button\u003e\n    \u003cbutton onclick=\"NotifyX.clear()\"\u003eClear All\u003c/button\u003e\n    \n    \u003c!-- NotifyX JavaScript --\u003e\n    \u003cscript src=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.js\"\u003e\u003c/script\u003e\n    \n    \u003cscript\u003e\n        // Show welcome message on page load\n        window.addEventListener('DOMContentLoaded', () =\u003e {\n            NotifyX.info('Welcome! Click any button to see notifications.', {\n                duration: 5000,\n                position: 'top-right'\n            });\n        });\n        \n        // Custom function with configuration\n        function showCustomToast() {\n            NotifyX.show({\n                message: 'Custom notification with all options!',\n                type: 'success',\n                position: 'bottom-right',\n                duration: 4000,\n                dismissible: true,\n                onClose: () =\u003e console.log('Toast closed!')\n            });\n        }\n    \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n---\n\n## 📘 Complete API Reference\n\n### Methods\n\n#### `NotifyX.show(options)`\n\nDisplay a notification with full configuration options.\n\n**Parameters:**\n- `options` (object) - Configuration object\n\n**Example:**\n```javascript\nNotifyX.show({\n  message: 'Profile updated!',\n  type: 'success',\n  position: 'bottom-right',\n  duration: 5000,\n  dismissible: true,\n  onClose: () =\u003e console.log('Closed'),\n  maxToasts: 5\n});\n```\n\n---\n\n#### `NotifyX.success(message, options?)`\n\nShow a success notification.\n\n**Parameters:**\n- `message` (string) - Notification message\n- `options` (object, optional) - Override default options\n\n**Example:**\n```javascript\nNotifyX.success('File uploaded successfully!');\nNotifyX.success('Saved!', { duration: 2000, position: 'bottom-right' });\n```\n\n---\n\n#### `NotifyX.error(message, options?)`\n\nShow an error notification.\n\n**Parameters:**\n- `message` (string) - Error message\n- `options` (object, optional) - Override default options\n\n**Example:**\n```javascript\nNotifyX.error('Failed to connect to server');\nNotifyX.error('Invalid credentials', { duration: 5000 });\n```\n\n---\n\n#### `NotifyX.warning(message, options?)`\n\nShow a warning notification.\n\n**Parameters:**\n- `message` (string) - Warning message\n- `options` (object, optional) - Override default options\n\n**Example:**\n```javascript\nNotifyX.warning('Your session will expire soon');\nNotifyX.warning('Unsaved changes', { duration: 0 }); // Persistent\n```\n\n---\n\n#### `NotifyX.info(message, options?)`\n\nShow an info notification.\n\n**Parameters:**\n- `message` (string) - Info message\n- `options` (object, optional) - Override default options\n\n**Example:**\n```javascript\nNotifyX.info('New features available!');\nNotifyX.info('Loading...', { duration: 0 }); // Stays until cleared\n```\n\n---\n\n#### `NotifyX.clear()`\n\nRemove all active notifications immediately.\n\n**Example:**\n```javascript\nNotifyX.clear(); // Removes all toasts\n```\n\n---\n\n### TypeScript Support\n\nNotifyX is built with TypeScript and exports comprehensive types:\n\n```typescript\nimport NotifyX, { \n  ToastOptions, \n  ToastType, \n  Position,\n  POSITIONS,\n  DEFAULT_OPTIONS\n} from 'notifyx';\n\n// Type-safe notification\nconst options: ToastOptions = {\n  message: 'Type-safe notification!',\n  type: 'success',\n  position: 'top-right',\n  duration: 3000,\n  dismissible: true,\n  onClose: () =\u003e console.log('Closed')\n};\n\nNotifyX.show(options);\n\n// Using type unions\nconst notificationType: ToastType = 'error';\nconst notificationPosition: Position = POSITIONS.BOTTOM_LEFT;\n\nNotifyX.show({\n  message: 'Using TypeScript types',\n  type: notificationType,\n  position: notificationPosition\n});\n```\n\n#### Available Types\n\n```typescript\ntype ToastType = 'success' | 'error' | 'warning' | 'info';\n\ntype Position = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';\n\ninterface ToastOptions {\n  message: string;\n  type?: ToastType;\n  duration?: number;\n  position?: Position;\n  dismissible?: boolean;\n  onClose?: () =\u003e void;\n  maxToasts?: number;\n}\n```\n\n---\n\n### Constants\n\n#### `POSITIONS`\n\nPredefined position constants for type safety:\n\n```javascript\nimport { POSITIONS } from 'notifyx';\n\nPOSITIONS.TOP_RIGHT     // 'top-right'\nPOSITIONS.TOP_LEFT      // 'top-left'\nPOSITIONS.BOTTOM_RIGHT  // 'bottom-right'\nPOSITIONS.BOTTOM_LEFT   // 'bottom-left'\n```\n\n#### `DEFAULT_OPTIONS`\n\nDefault configuration values:\n\n```javascript\nimport { DEFAULT_OPTIONS } from 'notifyx';\n\nconsole.log(DEFAULT_OPTIONS);\n// {\n//   type: 'info',\n//   duration: 3000,\n//   position: 'top-right',\n//   dismissible: true,\n//   maxToasts: 5\n// }\n```\n\n#### `ANIMATION_CLASSES`\n\nCSS animation class names:\n\n```javascript\nimport { ANIMATION_CLASSES } from 'notifyx';\n\nANIMATION_CLASSES.enter       // 'notifyx-enter'\nANIMATION_CLASSES.exit        // 'notifyx-exit'\nANIMATION_CLASSES.slideEnter  // 'notifyx-slide-enter'\nANIMATION_CLASSES.slideExit   // 'notifyx-slide-exit'\n```\n\n---\n\n## 🎨 Customization \u0026 Theming\n\n### Custom CSS Styling\n\nOverride default styles with your own CSS:\n\n```css\n/* Custom toast container positioning */\n.notifyx-container[data-position=\"top-right\"] {\n  top: 20px;\n  right: 20px;\n}\n\n/* Custom toast appearance */\n.notifyx {\n  border-radius: 12px;\n  padding: 16px 20px;\n  font-family: 'Inter', sans-serif;\n  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);\n}\n\n/* Success toast gradient */\n.notifyx-success {\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  color: white;\n  border: none;\n}\n\n/* Error toast gradient */\n.notifyx-error {\n  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n  color: white;\n  border: none;\n}\n\n/* Warning toast */\n.notifyx-warning {\n  background: #fbbf24;\n  color: #78350f;\n  border: 2px solid #f59e0b;\n}\n\n/* Info toast */\n.notifyx-info {\n  background: #3b82f6;\n  color: white;\n  border: none;\n}\n\n/* Customize close button */\n.notifyx-close {\n  background: rgba(255, 255, 255, 0.2);\n  border-radius: 50%;\n  width: 24px;\n  height: 24px;\n  font-size: 14px;\n}\n\n.notifyx-close:hover {\n  background: rgba(255, 255, 255, 0.3);\n  transform: scale(1.1);\n}\n\n/* Dark mode custom styles */\n@media (prefers-color-scheme: dark) {\n  .notifyx {\n    background: rgba(30, 30, 30, 0.95);\n    border: 1px solid rgba(255, 255, 255, 0.1);\n    backdrop-filter: blur(10px);\n  }\n  \n  .notifyx-success {\n    background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n  }\n}\n\n/* Custom animations */\n@keyframes customSlideIn {\n  from {\n    transform: translateX(100%);\n    opacity: 0;\n  }\n  to {\n    transform: translateX(0);\n    opacity: 1;\n  }\n}\n\n.notifyx-enter {\n  animation: customSlideIn 0.3s ease-out;\n}\n```\n\n### Tailwind CSS Integration\n\nExtend NotifyX styles with Tailwind classes:\n\n```javascript\n// After showing a toast, add Tailwind classes\nconst toast = document.querySelector('.notifyx:last-child');\ntoast.classList.add('backdrop-blur-md', 'shadow-2xl', 'ring-2', 'ring-blue-500');\n```\n\nOr create a wrapper function:\n\n```javascript\nfunction showStyledToast(message, type = 'info') {\n  NotifyX[type](message);\n  \n  setTimeout(() =\u003e {\n    const toast = document.querySelector('.notifyx:last-child');\n    if (toast) {\n      toast.classList.add('backdrop-blur-md', 'shadow-2xl');\n    }\n  }, 10);\n}\n```\n\n---\n\n## ⚡ Performance Tips\n\n1. **Limit Maximum Toasts**: Control memory usage\n   ```javascript\n   NotifyX.show({ message: 'Hello', maxToasts: 3 });\n   ```\n\n2. **Clear Old Notifications**: Remove unnecessary toasts\n   ```javascript\n   NotifyX.clear(); // Clear all before showing new batch\n   ```\n\n3. **Use Appropriate Durations**: Don't keep toasts open unnecessarily\n   ```javascript\n   // Quick actions\n   NotifyX.success('Copied!', { duration: 1000 });\n   \n   // Important info\n   NotifyX.warning('Read carefully', { duration: 5000 });\n   ```\n\n4. **Batch Operations**: Clear between batches\n   ```javascript\n   function processBatch() {\n     NotifyX.clear(); // Clear previous\n     NotifyX.info('Processing batch...');\n   }\n   ```\n\n---\n\n## 🐛 Troubleshooting\n\n### Styles Not Showing\n\n**Problem**: Notifications appear but have no styles.\n\n**Solution**: Make sure you've imported the CSS:\n```javascript\nimport 'notifyx/style.css';\n```\n\nFor CDN:\n```html\n\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.css\"\u003e\n```\n\n---\n\n### NotifyX is Not Defined (Vanilla JS)\n\n**Problem**: `ReferenceError: NotifyX is not defined`\n\n**Solution**: Ensure the script is loaded before use:\n```html\n\u003cscript src=\"https://unpkg.com/notifyx@latest/dist/notifyx.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  // Now you can use NotifyX\n  NotifyX.success('Works!');\n\u003c/script\u003e\n```\n\n---\n\n### Next.js \"window is not defined\"\n\n**Problem**: Error during server-side rendering.\n\n**Solution**: Use client components:\n```tsx\n'use client'; // Add this at the top\n\nimport NotifyX from 'notifyx';\n```\n\n---\n\n### Multiple Instances in React\n\n**Problem**: Multiple toasts appear on re-renders.\n\n**Solution**: Use `useCallback` or `useMemo`:\n```jsx\nconst showToast = useCallback(() =\u003e {\n  NotifyX.success('Success!');\n}, []);\n```\n\n---\n\n## 📱 Browser Compatibility\n\nNotifyX works on all modern browsers:\n\n| Browser | Minimum Version |\n|---------|----------------|\n| Chrome | 60+ |\n| Firefox | 55+ |\n| Safari | 12+ |\n| Edge | 79+ |\n| Opera | 47+ |\n| Samsung Internet | 8+ |\n\n**Mobile Support**: ✅ iOS Safari 12+, Chrome Mobile, Firefox Mobile\n\n---\n\n## 🤝 Contributing\n\nWe welcome contributions! Here's how you can help:\n\n1. **Report Bugs**: [Open an issue](https://github.com/awalhadi/notifyx/issues)\n2. **Suggest Features**: [Start a discussion](https://github.com/awalhadi/notifyx/discussions)\n3. **Submit PRs**: Fork, create a branch, and submit a pull request\n4. **Improve Docs**: Help us make this README even better!\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/awalhadi/notifyx.git\ncd notifyx\n\n# Install dependencies\nnpm install\n\n# Build the project\nnpm run build\n\n# Run development server\nnpm run dev\n```\n\n---\n\n## 📄 License\n\nMIT License - feel free to use NotifyX in your personal and commercial projects!\n\nCopyright (c) 2025 A Awal Hadi\n\n---\n\n## 🙏 Acknowledgments\n\n- Built with ❤️ using [TypeScript](https://www.typescriptlang.org/)\n- Styled with [Tailwind CSS](https://tailwindcss.com/)\n- Bundled with [Vite](https://vitejs.dev/)\n- Inspired by modern notification libraries\n\n---\n\n## 📞 Support \u0026 Community\n\n- **GitHub**: [github.com/awalhadi/notifyx](https://github.com/awalhadi/notifyx)\n- **Issues**: [Report a bug](https://github.com/awalhadi/notifyx/issues)\n- **npm**: [npmjs.com/package/notifyx](https://www.npmjs.com/package/notifyx)\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**Made with ❤️ by [A Awal Hadi](https://github.com/awalhadi)**\n\nIf NotifyX helped your project, consider giving it a ⭐ on GitHub!\n\n[⬆ Back to Top](#-notifyx)\n\n\u003c/div\u003e\n","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Notifications"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawalhadi%2Fnotifyx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawalhadi%2Fnotifyx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawalhadi%2Fnotifyx/lists"}