Home/Docs/Next.js

Next.js Integration

React Toast Kit works with both the Next.js App Router and Pages Router. Below are setup guides, patterns, and things to avoid.

Live Demo

This page runs inside a Next.js App Router app — try it:

App Router Setup

The simplest approach: add 'use client' to your root layout and wrap the body with ToastProvider.

app/layout.tsx
1// app/layout.tsx
2'use client'; // Required when using hooks inside the layout
3
4import { ToastProvider } from 'react-toast-kit';
5import './globals.css';
6
7export default function RootLayout({ children }: { children: React.ReactNode }) {
8  return (
9    <html lang="en">
10      <body>
11        <ToastProvider theme="system" position="top-right">
12          {children}
13        </ToastProvider>
14      </body>
15    </html>
16  );
17}

Recommended: To preserve Server Component benefits on the root layout, extract ToastProvider into a separate client wrapper component.

app/layout.tsx
1// app/layout.tsx  (Server Component — recommended pattern)
2import type { Metadata } from 'next';
3import './globals.css';
4import ToastWrapper from './ToastWrapper'; // client component
5
6export const metadata: Metadata = { title: 'My App' };
7
8export default function RootLayout({ children }: { children: React.ReactNode }) {
9  return (
10    <html lang="en">
11      <body>
12        <ToastWrapper>{children}</ToastWrapper>
13      </body>
14    </html>
15  );
16}
17
18// app/ToastWrapper.tsx
19'use client';
20import { ToastProvider } from 'react-toast-kit';
21
22export default function ToastWrapper({ children }: { children: React.ReactNode }) {
23  return <ToastProvider theme="system">{children}</ToastProvider>;
24}

Pages Router Setup

Add ToastProvider to your _app.tsx file:

pages/_app.tsx
1// pages/_app.tsx  (Pages Router)
2import type { AppProps } from 'next/app';
3import { ToastProvider } from 'react-toast-kit';
4import '../styles/globals.css';
5
6export default function MyApp({ Component, pageProps }: AppProps) {
7  return (
8    <ToastProvider theme="system" position="top-right">
9      <Component {...pageProps} />
10    </ToastProvider>
11  );
12}

Using in Client Components

toast() calls the Zustand store — it only runs in the browser. Always import and call it inside 'use client' components.

LoginButton.tsx
1'use client'; // Required — toast() cannot be called in Server Components
2
3import { toast } from 'react-toast-kit';
4
5export default function LoginButton() {
6  const handleLogin = async () => {
7    try {
8      await signIn(credentials);
9      toast.success({ title: 'Welcome back!', description: 'You are now signed in.' });
10    } catch (err) {
11      toast.error({ title: 'Login failed', description: err.message });
12    }
13  };
14
15  return <button onClick={handleLogin}>Sign in</button>;
16}

Server Actions Pattern

Server Actions run on the server — you cannot call toast() inside them. Instead, return the result to the client and toast from there.

1// app/actions.ts  (Server Action)
2'use server';
3
4export async function saveData(formData: FormData) {
5  await db.save(formData);
6  // ✗ Cannot call toast() here — Server Action runs on the server
7  return { success: true };
8}
9
10// app/SaveForm.tsx  (Client Component)
11'use client';
12import { toast } from 'react-toast-kit';
13import { saveData } from './actions';
14
15export default function SaveForm() {
16  const handleSubmit = async (formData: FormData) => {
17    const result = await saveData(formData);
18    if (result.success) {
19      toast.success('Saved!'); // ✓ Called in client component
20    }
21  };
22
23  return <form action={handleSubmit}>...</form>;
24}

Fixed Header Offset

If your app has a fixed header, use topOffset to push toasts below it:

// Account for a fixed 64px header
<ToastProvider topOffset={80}>
  {children}
</ToastProvider>

Integration Checklist

ToastProvider is mounted once at the app root
toast() is only called inside client components
CSS is auto-injected — no import needed
ToastProvider receives topOffset if you have a fixed navbar
Accessibility announcements enabled for important alerts