Skip to content

About

A modern, fully customizable toast notification library for React and Next.js applications.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

React Toastify

npm version License: MIT TypeScript React

A modern, fully customizable toast notification library for React and Next.js applications.


✨ Features

  • 🎨 Beautiful & Modern β€” Clean design with smooth animations
  • πŸŒ“ Dark / Light / System β€” Automatic theme support out of the box
  • 🎯 Fully Customizable β€” Positions, durations, colors, icons, and actions
  • πŸ“¦ Lightweight β€” Minimal bundle size with only Zustand as a dependency
  • ⚑ TypeScript β€” 100% type-safe with full IntelliSense support
  • πŸš€ Next.js Ready β€” Works seamlessly with Server Components and the App Router
  • πŸ“± Responsive β€” Optimized for all devices and screen sizes
  • β™Ώ Accessible β€” ARIA-friendly with keyboard navigation support
  • πŸ”„ Loading States β€” Built-in loading toasts with update capabilities
  • 🎭 Multiple Positions β€” 6 different positions
  • ⏱️ Progress Bar β€” Visual timer indicator with pause-on-hover support
  • πŸŽͺ Smooth Animations β€” Elegant enter and exit animations
  • 🎨 CSS Isolated β€” Pure CSS with a z-toast-* prefix, so it won't conflict with your styles

πŸ“¦ Installation

npm

npm install @zyther/react-toastify

Yarn

yarn add @zyther/react-toastify

pnpm

pnpm add @zyther/react-toastify

πŸš€ Quick Start

1. Create a Client Wrapper

Important

Since ToastProvider uses client-side hooks (useEffect, useState), you need to wrap it in a Client Component before using it in your Server Component layout.

Create app/components/ClientWrapper.tsx:

'use client';

import { ToastProvider } from "@zyther/react-toastify";
import "@zyther/react-toastify/styles";

interface ClientWrapperProps {
  children: React.ReactNode;
}

export function ClientWrapper({ children }: ClientWrapperProps) {
  return (
    <ToastProvider
      defaultPosition="bottom-right"
      defaultDuration={4000}
      maxToasts={5}
      theme="system"
    >
      {children}
    </ToastProvider>
  );
}

2. Wrap Your App in layout.tsx

app/layout.tsx (Server Component):

import { ClientWrapper } from "@/components/ClientWrapper";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <ClientWrapper>
          {children}
        </ClientWrapper>
      </body>
    </html>
  );
}

3. Use the useToast Hook

Important

The useToast hook must be used in Client Components with the "use client" directive.

"use client";

import { useToast } from "@zyther/react-toastify";

export default function MyComponent() {
  const toast = useToast();

  const handleClick = () => {
    toast.success("Operation completed successfully! πŸŽ‰", {
      title: "Success",
      duration: 4000,
    });
  };

  return (
    <button onClick={handleClick}>
      Show Toast
    </button>
  );
}

πŸ“– Usage Examples

Basic Examples

"use client";

import { useToast } from "@zyther/react-toastify";

function Demo() {
  const toast = useToast();

  // Success toast
  toast.success("Data saved successfully!");

  // Error toast with an action button
  toast.error("Failed to save data", {
    title: "Error",
    action: {
      label: "Retry",
      onClick: () => console.log("Retrying..."),
    },
  });

  // Warning toast
  toast.warning("Please check your input fields");

  // Info toast
  toast.info("New version available", {
    duration: 5000,
  });

  // Loading toast with update
  const id = toast.loading("Processing your request...");

  setTimeout(() => {
    toast.updateToast(id, {
      type: "success",
      message: "Request completed!",
      duration: 3000,
    });
  }, 2000);
}

Custom Positions

toast.success("Top right!", {
  position: "top-right",
});

toast.info("Top left!", {
  position: "top-left",
});

toast.warning("Top center!", {
  position: "top-center",
});

toast.error("Bottom right!", {
  position: "bottom-right",
});

toast.success("Bottom left!", {
  position: "bottom-left",
});

toast.info("Bottom center!", {
  position: "bottom-center",
});

Custom Duration

Disable automatic dismissal:

toast.info("This stays until dismissed", {
  duration: 0,
});

Custom duration in milliseconds:

toast.success("Short toast", {
  duration: 2000,
});

toast.success("Long toast", {
  duration: 8000,
});

Actions & Interactions

toast.error("Connection lost", {
  title: "Network Error",
  duration: 5000,
  action: {
    label: "Reconnect",
    onClick: () => {
      console.log("Reconnecting...");
    },
  },
  onClose: () => {
    console.log("Toast closed");
  },
});

Dismiss Methods

const toast = useToast();

// Dismiss a specific toast by ID
const id = toast.info("Hello!");
toast.dismissToast(id);

// Dismiss all active toasts
toast.dismissAll();

🎯 API Reference

ToastProvider Props

Prop Type Default Description
defaultPosition ToastPosition "bottom-right" Default position for all toasts
defaultDuration number 4000 Default duration in milliseconds. 0 disables auto-dismiss
maxToasts number 5 Maximum number of visible toasts
theme "light" | "dark" | "system" "system" Theme mode

ToastPosition

type ToastPosition =
  | "top-right"
  | "top-left"
  | "top-center"
  | "bottom-right"
  | "bottom-left"
  | "bottom-center";

useToast Return Value

interface UseToastReturn {
  showToast: (
    message: string,
    options?: ToastOptions
  ) => string;

  success: (
    message: string,
    options?: Omit<ToastOptions, "type">
  ) => string;

  error: (
    message: string,
    options?: Omit<ToastOptions, "type">
  ) => string;

  warning: (
    message: string,
    options?: Omit<ToastOptions, "type">
  ) => string;

  info: (
    message: string,
    options?: Omit<ToastOptions, "type">
  ) => string;

  loading: (
    message: string,
    options?: Omit<ToastOptions, "type">
  ) => string;

  updateToast: (
    id: string,
    updates: Partial<Toast>
  ) => void;

  dismissToast: (id: string) => void;

  dismissAll: () => void;
}

ToastOptions

Option Type Default Description
type ToastType "info" Toast type
title string undefined Optional title
duration number 4000 Duration in milliseconds. 0 disables auto-dismiss
position ToastPosition "bottom-right" Toast position
icon React.ReactNode undefined Custom icon
action { label: string; onClick: () => void } undefined Action button
onClose () => void undefined Callback invoked when the toast closes

🎨 Custom Styling

Isolated CSS

The library uses pure CSS with the z-toast-* prefix to avoid conflicts with your application's styles. No Tailwind CSS is required.

Override Default Styles

You can override the default styles in your own CSS:

/* Override toast item styles */
.z-toast-item {
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
}

/* Override success toast */
.z-toast-success {
  background-color: #dcfce7;
  border-color: #22c55e;
}

Custom Icons

toast.info("Custom icon!", {
  icon: <CustomIcon />,
});

πŸ§ͺ TypeScript

The library is fully typed and provides complete TypeScript support.

You can import the available types directly from the package:

import type {
  Toast,
  ToastOptions,
  ToastType,
  ToastPosition,
  ToastProviderProps,
} from "@zyther/react-toastify";

🌟 Best Practices

Next.js App Router Setup

1. Create a Client Wrapper

// app/components/ClientWrapper.tsx

'use client';

import { ToastProvider } from "@zyther/react-toastify";
import "@zyther/react-toastify/styles";

export function ClientWrapper({ children }) {
  return <ToastProvider>{children}</ToastProvider>;
}

2. Use It in Your Layout

// app/layout.tsx

import { ClientWrapper } from "@/components/ClientWrapper";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ClientWrapper>{children}</ClientWrapper>
      </body>
    </html>
  );
}

3. Use the Hook in Client Components

// app/page.tsx

'use client';

import { useToast } from "@zyther/react-toastify";

export default function Page() {
  const toast = useToast();

  return (
    <button onClick={() => toast.success("Hello!")}>
      Click me
    </button>
  );
}

Toast IDs

Store toast IDs when you need to update or dismiss a specific toast later:

const id = toast.loading("Processing...");

// Later
toast.updateToast(id, {
  type: "success",
  message: "Done!",
});

Duration

Use duration: 0 for important messages that require the user to manually dismiss them.

Actions

Keep action callbacks simple and avoid placing heavy business logic directly inside the toast action.


πŸ› οΈ Troubleshooting

"You're importing a module that depends on useEffect" Error

Solution: Create a Client Wrapper component as shown in the Quick Start section. Never import ToastProvider directly in a Server Component.

// ❌ Wrong - Direct import in Server Component
// app/layout.tsx

import { ToastProvider } from "@zyther/react-toastify";

// βœ… Correct - Use Client Wrapper
// app/components/ClientWrapper.tsx

'use client';

import { ToastProvider } from "@zyther/react-toastify";

Styles Not Working

Solution: Import the styles once in your Client Wrapper:

import "@zyther/react-toastify/styles";

useToast Not Working

Solution: Add the "use client" directive to your component:

"use client";

import { useToast } from "@zyther/react-toastify";

πŸš€ Performance

  • Minimal Bundle β€” Approximately 6 KB gzipped
  • Optimized Renders β€” Uses Zustand for efficient state management
  • Memoized Components β€” Toast items are memoized for improved performance
  • Lazy Rendering β€” Only renders toast content when needed
  • No Dependencies β€” Only Zustand, no other external libraries

🀝 Contributing

Contributions are welcome!

  1. Fork the repository.

  2. Create your feature branch:

    git checkout -b feature/amazing-feature
  3. Commit your changes:

    git commit -m "Add some amazing feature"
  4. Push to the branch:

    git push origin feature/amazing-feature
  5. Open a Pull Request.


πŸ“š Changelog

See CHANGELOG.md for the version history.


πŸ› Bug Reports

Found a bug or unexpected behavior?

Please report it through GitHub Issues with:

  • A clear description of the problem
  • Steps to reproduce it
  • Your React and Next.js versions
  • Your browser and operating system
  • Any relevant error messages or screenshots

πŸ“ License

MIT Β© zytherdev

About

A modern, fully customizable toast notification library for React and Next.js applications.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages