tohokuaikiのチラシの裏

技術的ネタとか。

Laravel Breeze(Inertia.js + React)で、ログイン後に別のReactに移動するのをしたかった。

タイトルだけだとわけわからんね。

課題

管理画面と一般画面を分けたくて、別のReactにしている。こういう時に管理画面のJavaScriptも見せたくないので、2つのReactを1つのLaravelに同居させるようにしている。

Laravel のInertia.js+Reactって、Devモードだと

<script type="module" src="http://localhost:5173/resources/js/app.tsx"></script>
<script type="module" src="http://localhost:5173/resources/js/Pages/Default.tsx"></script>

ってHTMLが起点なんだけど管理画面は、

<script type="module" src="http://localhost:5173/resources/js/admin.tsx"></script>
<script type="module" src="http://localhost:5173/resources/js/Pages/Admin/Default.tsx"></script>

ってなるようにしたいんだよね。

そしたら、ログイン後に問題が発生した。以下のようなケース。

  1. 管理画面URLにアクセス
  2. 未ログインなので、ログイン画面に飛ばされる
  3. ログイン成功するも当初アクセスした管理画面URLにリダイレクトされない。(なぜ?)

なぜ?って、ログイン画面って、app.tsxの作ってる一般画面Reactなんですよね。ログイン成功後にRedirectするんだけど、そのRedirect先はログイン前にアクセスした管理画面なんで、管理画面のInertiaレスポンスを返してくれるんだけど、それは一般画面のapp.tsx内には無いからエラーでダメって言う。

解決方法

Inertia.jsのredirectじゃなくって、JavaScriptのlocation.hrefを使ってやればいい。といっても、InertiaのAjaxはInertiaレスポンスを返さないといけないっぽいから、普通にJSONとかで返すのではなく、Inertia::location()を使うとよい。(とChatGPTに教えてもらった)

<?php
class AuthenticatedSessionController extends Controller
{
    public function store(LoginRequest $request): \Symfony\Component\HttpFoundation\Response
    {
        $request->authenticate();

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

        $redirect_url = $request->session()->pull('url.intended', url('/'));

        return Inertia::location($redirect_url);
    }

解決!!