🏐

【React】Next.js環境でMantineのNotifications機能を使って通知を表示

に公開

概要

UIのコンポーネントライブラリ「Mantine」では、トーストのような通知など表示するNotificationsの機能があります。表示位置や自動クローズなど、react-toastifyに似た機能が実装されており、個人的には良いなと思いましたのでNext.js環境で使ってみた結果のメモ書きです。

前提

  • 使用したmantineのバージョンは7.17.2です。
  • 使用したNext.jsのバージョンは15.2.3です。

実装サンプル

まずはlayout.tsxに事前準備の設定をします。具体的にはCSSの読み込みとNotificationsのコンポーネントの読み込みを行います。

layout.tsx
import {
  ColorSchemeScript,
  mantineHtmlProps,
  MantineProvider,
} from "@mantine/core";
import { Notifications } from "@mantine/notifications";
@import "@mantine/core/styles.css";
@import '@mantine/notifications/styles.css';
import { Geist, Geist_Mono } from "next/font/google";

import "./globals.css";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja" {...mantineHtmlProps}>
      <head>
        <ColorSchemeScript />
        <link rel="shortcut icon" href="/favicon.svg" />
        <meta
          name="viewport"
          content="minimum-scale=1, initial-scale=1, width=device-width, user-scalable=no"
        />
      </head>
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <MantineProvider>
          <Notifications />
          {children}
        </MantineProvider>
      </body>
    </html>
  );
}

そして以下のような通知を表示させてみます。メニューからログアウトを押したら、通知が表示されるようなイメージでの実装です。

"use client";
"use client";

import { FC } from "react";
import { Button, Menu } from "@mantine/core";
import { notifications } from "@mantine/notifications";

export const SampleComponent: FC = ({}) => {
  const onClickLogout = () => {
    // 通知の表示
    notifications.show({
      id: "logout-success",
      position: "top-center",
      withCloseButton: true,
      autoClose: 5000,
      title: "ログアウト",
      message: "ログアウトしました。",
      color: "blue",
      loading: false,
    });
  };

  return (
    <Menu
      position="bottom-start"
      offset={3}
      width={250}
      styles={{
        item: {
          marginBottom: "12px",
        },
      }}
    >
      <Menu.Target>
        <Button>Toggle menu</Button>
      </Menu.Target>
      <Menu.Dropdown>
        <Menu.Item onClick={onClickLogout}>
          <span className="text-lg">ログアウト</span>
        </Menu.Item>
      </Menu.Dropdown>
    </Menu>
  );
};

Discussion