How to use React-Toastify with Next.js App router
Tags: nextjs, reacttoastify, approuter, typescript
Published: 2024-02-05 20:14:54

---
title: How to use React-Toastify with Next.js App router
published: true
description: 
tags: nextjs, reacttoastify, approuter, typescript
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-02-05 08:46 +0000
---

React-Toastify is one of the most popular toast UI libraries for React or Next.js. It's easy to configure and use, but integrating it with the App router makes the configuration part a bit tricky.
There is an [open issue](https://github.com/fkhadra/react-toastify/issues/963) about this topic, and while you can find some solutions there, they aren't summarized.
So in this article, I'll provide a summarized version of the solution to integrate React-Toastify with Next.js App router.

# ToastProvider component as a client component wrapper for ToastContainer
The `ToastContainer` should be placed inside a client component. In the Pages router, you can simply put the ToastContainer component in the root component, such as App.tsx. However, in the App component, the root component is app/layout.tsx, which is a server component by default. So you first need to create a client component wrapper like this:

```tsx
"use client";

import "react-toastify/dist/ReactToastify.css";
import "../../app/globals.css";
import { ToastContainer } from "react-toastify";

interface ToastProviderProps {
  children: React.ReactNode;
}

export default function ToastProvider({ children }: ToastProviderProps) {

  return (
    <>
      {children}
      <ToastContainer />
    </>
  );
}
```

If you need to change the default configuration, you can do it in this component. The sample code below uses Tailwind CSS:

```tsx
"use client";

import "react-toastify/dist/ReactToastify.css";
import "../../app/globals.css";
import { ToastContainer } from "react-toastify";

interface ToastProviderProps {
  children: React.ReactNode;
}

export default function ToastProvider({ children }: ToastProviderProps) {
  const contextClass = {
    success: "bg-blue-600",
    error: "bg-red-600",
    info: "bg-gray-600",
    warning: "bg-orange-400",
    default: "bg-indigo-600",
    dark: "bg-white-600 font-gray-300",
  };

  return (
    <>
      {children}
      <ToastContainer
        toastClassName={(context) =>
          contextClass[context?.type || "default"] +
          " relative flex p-1 min-h-10 rounded-md justify-between overflow-hidden cursor-pointer"
        }
        bodyClassName={() => "text-sm font-white font-med block p-3"}
        position="bottom-left"
        autoClose={3000}
      />
    </>
  );
}
```

# Use ToastProvider in the root layout component

After creating the ToastProvider component, simply place it in the root layout as a parent component of `children`.

```tsx
import type { Metadata } from "next"
import { Inter } from "next/font/google"
import Favicon from "@/app/icon.ico";
import "./globals.css"
import ToastProvider from "@/lib/react-toastify/ToastProvider"

const inter = Inter({ subsets: ["latin"] })

export const metadata: Metadata = {
  title: "Toast app",
  description: "Toast app is just a sample app for demonstrating react-toastify library.",
  icons: [{ rel: 'icon', url: Favicon.src }]
}

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

```

And that's it. Now, you can use the beautiful toast UIs of React-Toastify anywhere you want!

```typescript
toast('🦄 Wow so easy!', {
  position: "top-right",
  autoClose: 5000,
  hideProgressBar: false,
  closeOnClick: true,
  pauseOnHover: true,
  draggable: true,
  progress: undefined,
  theme: "light",
  transition: Bounce,
});
```

By the way, this is a bit off-topic, but in my project, I often implement a helper function to show toasts:

```typescript
import { toast, ToastContent, ToastOptions, Slide, Id } from "react-toastify";


export const defaultToastOptions: ToastOptions = {
  position: "top-center",
  autoClose: 4000,
  hideProgressBar: true,
  closeOnClick: true,
  pauseOnHover: true,
  draggable: true,
  progress: undefined,
  theme: "colored",
  transition: Slide,
};

type ToastType = "success" | "error" | "info" | "warning" | "default";

/**
 * Display toast
 *
 * @param {ToastType} type
 * @param {ToastContent} content
 * @param {ToastOptions} [options=defaultToastOption]
 * @return {Id}
 */
export const showToast = (
  type: ToastType,
  content: ToastContent,
  options: Partial<ToastOptions> = {},
): Id => {
  const optionsToApply = { ...defaultToastOptions, ...options };

  switch (type) {
    case "success":
      return toast.success(content, optionsToApply);
    case "error":
      return toast.error(content, optionsToApply);
    case "info":
      return toast.info(content, optionsToApply);
    case "warning":
      return toast.warn(content, optionsToApply);
    case "default":
      return toast(content, optionsToApply);
    default:
      return toast(content, optionsToApply);
  }
};
```

And use it like this:

```tsx
showToast("success" <p>Your post has been published!</p>);
```

This way, you can maintain consistency in handling toasts in your app.

I hope you find this article helpful. Thank you!