Beautiful, customizable toast notifications for React & Next.js
Simple setup. Full control. Light & Dark themes. That's it.
npm install coco-alert
import { AlertContainer, coco_Alert } from 'coco-alert/react';
function App() {
return (
<>
<AlertContainer
isLightMode={false}
position="top-right"
/>
<YourApp />
</>
);
}
import { coco_Alert } from 'coco-alert/react';
function MyComponent() {
return (
<button onClick={() => coco_Alert.success('It works! 🎉')}>
Click Me
</button>
);
}
That's it! No providers, no complex setup.
import { AlertContainer, coco_Alert } from 'coco-alert/react';
import { useState } from 'react';
function App() {
const [isLightMode, setIsLightMode] = useState(false);
return (
<>
<AlertContainer
isLightMode={isLightMode}
position="top-right"
/>
<div>
<h1>My App</h1>
<button onClick={() => setIsLightMode(!isLightMode)}>
Toggle Theme
</button>
<button onClick={() => coco_Alert.success('Success!')}>
Show Alert
</button>
</div>
</>
);
}
export default App;
'use client'; // Required for App Router!
import { AlertContainer, coco_Alert } from 'coco-alert/react';
export default function RootLayout({ children }) {
return (
<html>
<body>
<AlertContainer
isLightMode={false}
position="top-right"
/>
{children}
</body>
</html>
);
}
'use client';
import { coco_Alert } from 'coco-alert/react';
export default function Page() {
return (
<div>
<h1>Next.js App Router</h1>
<button onClick={() => coco_Alert.info('Hello from Next.js! 👋')}>
Show Alert
</button>
</div>
);
}
// pages/_app.tsx
import { AlertContainer } from 'coco-alert/react';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<AlertContainer
isLightMode={false}
position="top-right"
/>
<Component {...pageProps} />
</>
);
}
// pages/index.tsx
import { coco_Alert } from 'coco-alert/react';
export default function Home() {
return (
<div>
<h1>Next.js Pages Router</h1>
<button onClick={() => coco_Alert.success('It works! 🎉')}>
Show Alert
</button>
</div>
);
}
import { coco_Alert } from 'coco-alert/react';
async function handleSubmit(e) {
e.preventDefault();
try {
await submitForm(formData);
coco_Alert.success('Form submitted successfully! ✅');
} catch (error) {
coco_Alert.error('Failed to submit form. Please try again.');
}
}
import { coco_Alert } from 'coco-alert/react';
async function fetchData() {
try {
const response = await fetch('/api/data');
if (!response.ok) throw new Error('Failed to fetch');
const data = await response.json();
coco_Alert.success('Data loaded successfully!');
return data;
} catch (error) {
coco_Alert.error('Failed to load data');
}
}
import { coco_Alert } from 'coco-alert/react';
async function handleDelete(id) {
const confirmed = await coco_Alert.confirm('Delete this item? This cannot be undone.');
if (confirmed) {
try {
await deleteItem(id);
coco_Alert.success('Item deleted successfully!');
} catch (error) {
coco_Alert.error('Failed to delete item');
}
} else {
coco_Alert.info('Deletion cancelled');
}
}
import { AlertContainer, coco_Alert } from 'coco-alert/react';
import { useState } from 'react';
function App() {
const [isDark, setIsDark] = useState(true);
const toggleTheme = () => {
setIsDark(!isDark);
coco_Alert.info(`Switched to ${!isDark ? 'dark' : 'light'} mode`);
};
return (
<>
<AlertContainer
isLightMode={!isDark}
position="top-right"
/>
<button onClick={toggleTheme}>
Toggle Theme
</button>
</>
);
}
interface AlertContainerProps {
isLightMode?: boolean; // Default: false (dark mode)
position?: AlertPosition; // Default: "top-right"
}
// Dark mode, top-right (default)
<AlertContainer />
// Light mode, top-right
<AlertContainer isLightMode={true} />
// Dark mode, bottom-center
<AlertContainer position="bottom-center" />
// Light mode, center
<AlertContainer isLightMode={true} position="center" />
coco_Alert.success(message, duration?, position?);
coco_Alert.error(message, duration?, position?);
coco_Alert.warning(message, duration?, position?);
coco_Alert.info(message, duration?, position?);
| Parameter | Type | Default | Description |
|---|---|---|---|
message |
string |
required | The message to display |
duration |
number |
4000 |
Duration in milliseconds |
position |
AlertPosition |
Container's position | Override container position |
// Simple alert (uses container settings)
coco_Alert.success('Saved!');
// Custom duration
coco_Alert.error('Critical error', 10000);
// Override container position for this alert
coco_Alert.info('Loading...', 3000, 'center');
// All options
coco_Alert.warning('Session expiring', 5000, 'bottom-right');
const confirmed = await coco_Alert.confirm(message, position?);
Returns a Promise that resolves to:
true if user clicks "Confirm"false if user clicks "Cancel"// Simple confirmation
const result = await coco_Alert.confirm('Are you sure?');
if (result) {
console.log('User confirmed!');
}
// With custom position
const result = await coco_Alert.confirm('Delete this?', 'center');
// In async function
async function handleAction() {
const confirmed = await coco_Alert.confirm('Proceed with this action?');
if (confirmed) {
// Do something
coco_Alert.success('Action completed!');
}
}
Available positions for alerts:
type AlertPosition =
| "top-left"
| "top-right" // Default
| "top-center"
| "center"
| "bottom-left"
| "bottom-right"
| "bottom-center";
// Set container position (all alerts use this by default)
<AlertContainer position="bottom-center" />
// Override position for individual alerts
coco_Alert.info('Top alert', 3000, 'top-center');
coco_Alert.success('Center alert', 3000, 'center');
coco_Alert.warning('Bottom alert', 3000, 'bottom-left');
CocoAlert includes beautiful built-in themes:
// Dark mode
<AlertContainer isLightMode={false} />
// Light mode
<AlertContainer isLightMode={true} />
// Dynamic theme based on user preference
function App() {
const [isDark, setIsDark] = useState(true);
return (
<AlertContainer isLightMode={!isDark} />
);
}
// Sync with system preference
function App() {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
return (
<AlertContainer isLightMode={!prefersDark} />
);
}
🎨 Themes
|
📍 Positions
|
⚡ Simple API
|
🎭 Alert Types
|
📦 Tiny Bundle
|
🔧 Framework Support
|
// Show multiple alerts - they stack automatically!
coco_Alert.info('Loading...');
coco_Alert.success('Step 1 complete');
coco_Alert.success('Step 2 complete');
coco_Alert.success('All done! 🎉');
// 1 second quick notification
coco_Alert.success('Copied!', 1000);
// Use center position for critical messages
<AlertContainer position="center" />
coco_Alert.warning('Your session will expire in 5 minutes', 5000);
// Container uses top-right by default
<AlertContainer position="top-right" />
// But you can override for specific alerts
coco_Alert.error('Critical error!', 5000, 'center');
function App() {
const [theme, setTheme] = useState('dark');
useEffect(() => {
// Listen to system theme changes
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handler = (e) => setTheme(e.matches ? 'dark' : 'light');
mediaQuery.addEventListener('change', handler);
return () => mediaQuery.removeEventListener('change', handler);
}, []);
return <AlertContainer isLightMode={theme === 'light'} />;
}
| Type | Dark Mode | Light Mode | Use Case | Icon |
|---|---|---|---|---|
| Success | Green | Green | Successful operations | ✓ |
| Error | Red | Red | Errors, failures | ✕ |
| Warning | Yellow | Yellow | Warnings, cautions | ⚠ |
| Info | Blue | Blue | General information | ℹ |
| Confirm | Yellow | Yellow | User confirmations | ? |
Make sure you've added the AlertContainer to your root component:
// ✅ Correct
<AlertContainer />
// ❌ Wrong - no container
coco_Alert.success('Hello'); // Won't work without container!
Install React types:
npm install --save-dev @types/react @types/react-dom
Add 'use client'; at the top of files that use alerts:
'use client';
import { coco_Alert } from 'coco-alert/react';
Make sure you're using state to control isLightMode:
// ✅ Correct
const [isDark, setIsDark] = useState(false);
<AlertContainer isLightMode={!isDark} />
// ❌ Wrong - static value
<AlertContainer isLightMode={false} />
| Feature | CocoAlert | react-toastify | react-hot-toast | sonner |
|---|---|---|---|---|
| Setup Required | Container only | Container + Provider | Container + Provider | Provider |
| Light/Dark Themes | ✅ Built-in | ⚠️ Manual CSS | ⚠️ Manual CSS | ✅ Yes |
| Bundle Size | 3KB | 8KB | 4KB | 6KB |
| Dependencies | 0 | 2 | 1 | 3 |
| TypeScript | ✅ Built-in | ✅ Yes | ✅ Yes | ✅ Yes |
| Confirmation Dialog | ✅ Built-in | ❌ No | ❌ No | ❌ No |
| Position Control | ✅ Global + Override | ✅ Yes | ✅ Yes | ⚠️ Limited |
We welcome contributions! Here's how:
git checkout -b feature/amazing-featuregit commit -m 'Add amazing feature'git push origin feature/amazing-featureMIT © Cocobase Team
If you find CocoAlert helpful:
Made with 💙 by Dycoder
Beautiful alerts with full control.