Zenn
💡

laravel starter kit(react)でのtoastify (sonnar)

2025/03/07に公開

基本的にはshadcn/uiを使うのがよさそう

React-Toastifyもありますが、、、shadcn/uiのtoastを見てみると

npx shadcn@latest add toast
Need to install the following packages:
shadcn@2.4.0-canary.12
Ok to proceed? (y)


The toast component is deprecated. Use the sonner component instead.

となる。

sonnerを使う

そういうわけで今はsonnerを使うようだ

https://ui.shadcn.com/docs/components/sonner

npx shadcn@latest add sonner
✔ Checking registry.
  Installing dependencies.

It looks like you are using React 19.
Some packages may fail to install due to peer dependency issues in npm (see https://ui.shadcn.com/react-19).

✔ How would you like to proceed? › Use --force
✔ Installing dependencies.
✔ Created 1 file:
  - resources/js/components/ui/sonner.tsx
package.json
         "laravel-react-i18n": "^2.0.5",
         "laravel-vite-plugin": "^1.0",
         "lucide-react": "^0.475.0",
+        "next-themes": "^0.4.4",
         "react": "^19.0.0",
         "react-dom": "^19.0.0",
+        "sonner": "^2.0.1",
         "tailwind-merge": "^3.0.1",
         "tailwindcss": "^4.0.0",
         "tailwindcss-animate": "^1.0.7",

このようにdependencyも解消される

ログイン完了時にflashメッセージを仕込む

https://laravel.com/docs/12.x/redirects#redirecting-with-flashed-session-data

構造はいろいろ議論の余地を残すが今回はこういう風にしよう

app/Http/Controllers/Auth/AuthenticatedSessionController.php
    public function store(LoginRequest $request): RedirectResponse
    {
        $request->authenticate();

        $request->session()->regenerate();

        return redirect()->intended(route('dashboard', absolute: false))
          ->with('flashMessage', ['success' => __('You are now logged in.')]);
    }

flashMessageというキーで仕込んでいる。

組み込み

back

app/Http/Middleware/HandleInertiaRequests.php

@@ -45,6 +45,7 @@ public function share(Request $request): array
             'auth' => [
                 'user' => $request->user(),
             ],
+            'flashMessage' => session()->get('flashMessage', []),
         ];
     }
 }

front

一般的にはlayoutにつっこんだ方がよいと思われる。resources/js/layouts/app-layout.tsx に存在する auth-layout.tsxも存在するけどこれはまあ必要ないんじゃないかな。

resources/js/layouts/app-layout.tsx
@@ -1,14 +1,29 @@
+import { Toaster } from '@/components/ui/sonner';
 import AppLayoutTemplate from '@/layouts/app/app-sidebar-layout';
 import { type BreadcrumbItem } from '@/types';
-import { type ReactNode } from 'react';
+import { usePage } from '@inertiajs/react';
+import { useEffect, type ReactNode } from 'react';
+import { toast } from 'sonner';

 interface AppLayoutProps {
   children: ReactNode;
   breadcrumbs?: BreadcrumbItem[];
 }

-export default ({ children, breadcrumbs, ...props }: AppLayoutProps) => (
-  <AppLayoutTemplate breadcrumbs={breadcrumbs} {...props}>
-    {children}
-  </AppLayoutTemplate>
-);
+export default function AppLayout({ children, breadcrumbs, ...props }: AppLayoutProps) {
+  const { flashMessage } = usePage().props;
+  useEffect(() => {
+    if (flashMessage) {
+      Object.entries(flashMessage).forEach(([type, message]) => {
+        toast[type as keyof typeof toast](message);
+      });
+    }
+  }, [flashMessage]);
+
+  return (
+    <AppLayoutTemplate breadcrumbs={breadcrumbs} {...props}>
+      {children}
+      <Toaster />
+    </AppLayoutTemplate>
+  );
+}

言語

まあ何となく

ja.json
+  "You are now logged in.": "ログインしました。",

カスタマイズ

https://ui.shadcn.com/docs/components/sonner

descriptionactionも追加できるけどflashMessageの場合あんま必要とされる事がないかな...

Discussion

ログインするとコメントできます