Logo

dev-resources.site

for different kinds of informations.

How to use React-Toastify with Next.js App router

Published at
2/5/2024
Categories
nextjs
reacttoastify
approuter
typescript
Author
koyablue
Author
8 person written this
koyablue
open
How to use React-Toastify with Next.js App router

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 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:

"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 />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

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

"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}
      />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

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.

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>
  )
}

Enter fullscreen mode Exit fullscreen mode

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

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

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

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);
  }
};
Enter fullscreen mode Exit fullscreen mode

And use it like this:

showToast("success" <p>Your post has been published!</p>);
Enter fullscreen mode Exit fullscreen mode

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

I hope you find this article helpful. Thank you!

approuter Article's
23 articles in total
Favicon
Show a loading screen when changing pages in Next.js App router
Favicon
Learning Next.js 13 App Router: A Comprehensive Guide 🚀
Favicon
Guide to build a modern Web App using Next.js 14 (App Router), Fully authentication (NextAuth), Theming and i18n
Favicon
A practical Guide - Migrating to Next.js App Router
Favicon
Adding Chat Functionality To Your Next.Js Project With Firebase
Favicon
Spicing Up Your Next.Js Projects With 3D: What Are Your Options?
Favicon
No More Pages
Favicon
How To Create A Basic Infinity Canvas For Your Next.Js Project
Favicon
How To Implement Text-To-Speech Functionality For BlockNote In Next.Js
Favicon
How To Add Drag-And-Drop Functionality With Editable Draggable Items In Next.js
Favicon
Adding Drag And Drop Functionality In Your Next.Js Project Without A Library
Favicon
Creating NPM Packages in Next.Js for Next.Js
Favicon
Using Firebase To Store Folders and BlockNote Documents In Next.Js
Favicon
An Alternative To Editor.js: BlockNote For React
Favicon
How To Add Editor.Js To Your Next.Js Code
Favicon
How To Use The Quill Rich Text Editor in Your Next.Js App Router Project
Favicon
Simple NextJS GraphQL client
Favicon
Implementing Internationalization (i18n) in Next.js 14 using App Router
Favicon
Web Streams API in Action: Delivering 6000+ Log Lines Concurrently Across 20 Tabs
Favicon
How to use React-Toastify with Next.js App router
Favicon
NextAuth - Implementando "Custom Login Pages" com "Credentials Sign in" utilizando App Router
Favicon
The origin of App Router - A Next.Js Rewind
Favicon
How to add multiple routers in a node application without using app.use() for each router ?

Featured ones: