
ブラウザ向けの業務システムや管理画面を、Laravelの認証、ルーティング、バリデーションと一体で構築するなら、Inertia.jsは有力な選択肢になる。REST APIを別途設計せず、routes/web.phpとLaravelのコントローラーを使いながら、Vue、React、Svelteのコンポーネントで画面を構成できるためである。
一方で、同じデータをネイティブアプリ、外部サービス、複数のウェブクライアントへ提供する場合は事情が異なる。Inertia.jsはAPI基盤の代替ではない。Webアプリケーションの画面遷移を、サーバーサイドの責務を保ったままSPA風にするための仕組みである。
この境界を曖昧にすると、初期開発は速くても、後からAPIを分離する際に依存関係が増える。逆に、最初から完全分離型SPAを選ぶと、個人開発では不要な構成管理に時間を使うことになる。
Inertia.jsが実現するモダン・モノリス
Inertia.jsの特徴は、Laravelとフロントエンドを完全に分離しないことである。
従来のLaravelアプリケーションでは、コントローラーがビューへデータを渡し、BladeがHTMLを生成する。完全分離型SPAでは、LaravelはREST APIまたはGraphQL APIを提供し、VueやReactなどのフロントエンドがHTTP通信を通じてデータを取得する。
Inertia.jsは、この中間に位置する。
Laravelのルーティングとコントローラーを使い、レスポンスとしてフロントエンドコンポーネント名とPropsを返す。ブラウザ側では、ページ全体を毎回読み直す代わりに、必要なページコンポーネントを描画する。見た目はSPAに近い。しかし、バックエンドの入口は通常のLaravelルートであり、API専用のエンドポイント群ではない。
この構成は、一般にモダン・モノリスと呼ばれる。モノリスの保守性を残しながら、画面側には現代的なJavaScriptフレームワークを利用できる設計である。
完全分離型SPAとの構造差
両者の違いは、通信形式だけではない。責務の分割位置が異なる。
完全分離型SPAでは、次の要素を個別に設計する必要がある。
- APIのURLとHTTPメソッド
- レスポンス形式とエラー形式
- 認証方式とトークン管理
- CORSの許可範囲
- APIのバージョン管理
- スキーマ変更時の互換性
- フロントエンドとバックエンドのデプロイ単位
- キャッシュと再取得の戦略
Laravelの画面を一つ追加するだけでも、バックエンド側のAPI定義とフロントエンド側の通信処理が必要になる。画面が少ない段階では、この分割が開発速度のボトルネックになりやすい。
Inertia.jsでは、Laravelのコントローラーからページコンポーネントへ直接Propsを渡す。データ取得のためだけにAPIコントローラーを作り、専用のレスポンスリソースを定義し、フロントエンドで取得処理を書く必要がない。
Inertia.jsはSPAを作るためにAPIを増やすのではなく、APIを増やさずにSPA風の画面体験を作る選択肢である。
ただし、APIが不要になるのはWeb画面の内部に限られる。スマートフォンアプリや第三者向けサービスが同じデータを利用するなら、独立したREST APIまたはGraphQL APIが必要になる。
Inertia.jsの画面遷移
Inertia.jsの画面遷移では、通常のリンク遷移に近い操作で次のページのデータを取得する。ページ全体のHTMLを再構築するのではなく、サーバーから渡されたページ情報をフロントエンドコンポーネントへ適用する。
この方式の利点は、ルーティングの定義をLaravel側に集約できる点である。認証済みユーザーだけがアクセスできる画面、権限によって表示を制限する画面、フォーム送信後にリダイレクトする画面を、Laravelの既存機能で制御できる。
完全分離型SPAでは、フロントエンドのルーターとLaravel側のAPI認可が別に存在する。ブラウザで表示できるページと、APIにアクセスできる権限の整合性を管理しなければならない。Inertia.jsでは、この分離が小さくなる。
Laravel Breezeで構築を始める
個人開発でLaravelとSPAを組み合わせる場合、最初からすべてを手動で構成する必要はない。Laravel Breezeを利用すると、Inertia.jsとVueまたはReactを使う環境を短い手順で導入できる。
Reactを選択する場合は、php artisan breeze:install react、Vueを選択する場合は、対応するVue向けのインストールコマンドを実行する。これにより、認証画面、ルーティング、フロントエンドのビルド構成などがまとめて用意される。
[Inertia.jsのサーバー側パッケージを個別に追加する場合は、composer require inertiajs](/articles/docker-composenonei/)/inertia-laravelを実行する。その後、php artisan inertia:middlewareでミドルウェアを生成し、アプリケーションのHTTPカーネルまたはミドルウェア構成へ登録する。
Laravelのバージョンによって登録方法やスターターキットの構成は異なる。ここはコマンドを暗記するより、生成された構成を確認するべきである。特に次の部分は、導入後に確認が必要になる。
- InertiaのミドルウェアがWebリクエストへ適用されているか
- ルートテンプレートが正しく設定されているか
- ViteのエントリーポイントがVueまたはReact向けになっているか
- ページコンポーネントの探索先が実際のディレクトリと一致しているか
- 認証状態や共有Propsが意図した範囲で渡されているか
VueとReactの選択
Inertia.jsはVue、React、Svelteに対応する。どれを採用しても、Laravel側のルーティングとコントローラーを利用できる。したがって、フレームワーク選択の基準はInertia.jsとの機能差ではなく、チームや個人の実装経験で決めるのが合理的である。
Vueを使う場合は、単一ファイルコンポーネントとComposition APIを中心に画面を構成できる。テンプレートとロジックの対応が明確であり、LaravelのBladeに慣れた開発者でも移行しやすい。
Reactを使う場合は、JSXまたはTypeScriptのTSXでUIを定義する。既存のReact資産やUIコンポーネントを流用しやすい。Reactの状態管理、メモ化、コンポーネント分割に慣れているなら、Inertia.jsによる制約は少ない。
ただし、Inertia.jsを採用したからといって、フロントエンドの状態管理が不要になるわけではない。サーバーから受け取るページPropsと、入力途中のフォーム状態、モーダルの表示状態、画面内だけで使う一時データは別の責務である。
ここを一つの状態管理ストアへ集約すると、単純な画面でも依存関係が増える。ページPropsで十分なデータまでグローバル状態へ移す設計は、後から追跡しにくい。
Docker環境との組み合わせ
Laravel Sailを使う構成では、PHP、データベース、キャッシュ、Node.jsの実行環境をDocker上にまとめられる。Inertia.jsはフロントエンドのビルド処理を必要とするため、Viteをどのコンテナで実行するかを最初に決めておく必要がある。
開発中に発生しやすい問題は、アプリケーションコンテナから見たホスト名と、ブラウザから見たホスト名が異なることである。Viteの開発サーバーへ接続する際、コンテナ内部では解決できても、ブラウザからは到達できない場合がある。
この問題はInertia.js固有ではない。しかし、LaravelのレスポンスとJavaScriptのビルド環境を同時に扱うため、導入直後に表面化しやすい。
確認対象は次の通りである。
- Viteの開発サーバーが外部接続を受け付けているか
- 公開ポートがDocker Composeに定義されているか
- ブラウザが参照するホスト名とポートが正しいか
- ホットリロード用のWebSocket接続が遮断されていないか
- 本番ビルド済みアセットと開発用アセットが混在していないか
個人開発では、Dockerの設定を過剰に分割しない方がよい。PHPとNode.jsの責務を分けること自体は正しいが、開発者が一人の場合、コンテナ間の通信経路が増えるほど調査コストも増える。
APIエンドポイントを作らずにデータを渡す仕組み
Inertia.jsでは、Laravelのコントローラーからページ名とPropsを返す。たとえば一覧画面であれば、コントローラーがデータを取得し、ページコンポーネントへ渡す。
この処理は、従来のBladeへ変数を渡す処理と似ている。異なるのは、HTMLをBladeで組み立てる代わりに、VueやReactのコンポーネントがPropsを受け取って描画する点である。
ページの責務は、次のように分けられる。
- LaravelのルートがURLとHTTPメソッドを定義する
- コントローラーが認証、認可、データ取得を処理する
- リソースやクエリが返却データの形を整える
- Inertia.jsがページ情報をフロントエンドへ渡す
- VueまたはReactが画面を描画する
完全分離型SPAでは、これらに加えてAPIリソース、通信クライアント、APIエラー処理、ローディング状態を構築する必要がある。画面数が増えれば、同じような通信処理が複数箇所に現れる。
Propsの粒度が設計を左右する
Inertia.jsのPropsは便利である。しかし、コントローラーからデータベースのレコードをそのまま大量に渡す設計は避けるべきである。
理由は三つある。
一つ目は、レスポンスサイズが増えること。二つ目は、画面に不要なカラムまで公開するリスク。三つ目は、フロントエンドがデータベース構造へ依存することである。
一覧画面で必要なのが識別子、タイトル、更新日時だけなら、それ以外のカラムをPropsへ含める必要はない。LaravelのAPIリソースや専用のデータ変換処理を使い、画面の用途に合わせて返却値を制限するべきである。
これはREST APIを作る場合と同じ設計原則である。Inertia.jsはAPIエンドポイントを省略できるが、データ境界まで省略するものではない。
遅延評価と一覧データ
管理画面では、一覧、統計情報、関連データを一つのページに表示することがある。すべてのデータを初回レスポンスで取得すると、SQLの実行回数とレスポンスサイズが増える。
特に次のような処理は、ページの主目的と分離するべきである。
- 集計期間の異なるアクセス統計
- 件数の多い関連モデル
- 管理者だけが開く詳細情報
- 画面下部に配置された補助データ
- 表示条件によって利用されない検索候補
Inertia.jsでは、必要なデータをページPropsとして渡す設計と、操作時に取得する設計を組み合わせられる。初期表示に不要なデータまで一度に送らないことが、性能上の基本となる。
ただし、ここで非同期取得を増やしすぎると、完全分離型SPAと同じ複雑さへ近づく。ページの初回表示に必須のデータと、ユーザー操作後に必要なデータを分けるだけで十分なケースも多い。
バリデーションとフォーム処理
Inertia.jsの実用的な利点は、Laravelの標準バリデーションをそのまま活用できる点にある。
フォーム送信時にLaravel側でバリデーションを実行し、入力エラーがあれば通常のLaravelと同じ考え方で処理する。エラーメッセージはInertia.jsを通じてフロントエンドコンポーネントへ共有され、入力欄の近くに表示できる。
完全分離型SPAでは、APIの422エラーをフロントエンドで解釈し、フィールド名とエラーメッセージを画面の入力項目へ対応付ける処理が必要になる。API側のエラー形式を変更すると、フロントエンド側の処理も修正が必要になる。
Inertia.jsではこの接続部分が小さい。Laravelのフォームリクエストを使って入力ルールを定義し、フロントエンドでは受け取ったエラーを表示する。
フォーム送信で分けるべき状態
フォーム処理では、少なくとも次の状態を分ける必要がある。
- ユーザーが入力した値
- Laravelから返されたバリデーションエラー
- 送信中かどうか
- 送信成功後に表示する通知
- 送信失敗時のサーバーエラー
- 二重送信を防ぐための制御状態
Inertia.jsがこのすべてを自動管理するわけではない。送信中のボタンを無効化する、成功後にフォームを初期化する、失敗時に入力値を維持する、といったUI上の判断はフロントエンド側の責務である。
この点を誤ると、Inertia.jsを採用したのに、ページコンポーネント内へ状態管理処理が集中する。サーバー側のバリデーションと、ブラウザ側の即時入力チェックを同一視しないことも必要である。
ブラウザ側のチェックは操作性のために使う。認証やデータ整合性に関わる最終判定は、必ずLaravel側で実行する。フロントエンドの検証結果だけを信頼する設計は成立しない。
Inertia.jsで減るのは通信層の実装量であり、入力状態やUI状態の設計そのものではない。
リダイレクトを中心に考える
フォーム送信後の処理は、画面を直接書き換えるより、Laravel側で処理を完了させてリダイレクトする方が追跡しやすい。
登録、更新、削除の結果をサーバー側で確定し、次のページへ遷移させる。成功メッセージは共有Propsなどを通じて表示する。データの正しさをサーバー側に置くため、ブラウザの状態とデータベースの状態がずれにくい。
もちろん、入力途中の自動保存やリアルタイム編集のように、画面内で即時更新が必要な機能では別の設計が必要になる。しかし、一般的な管理画面やCRUDでは、すべてをJavaScriptだけで完結させる必要はない。
ルーティングと認証をLaravelに残す意味
Laravelを使う理由の一つは、認証、認可、セッション、CSRF対策、バリデーションを一つのアプリケーションで管理できることである。Inertia.jsは、この利点を失わずにフロントエンドだけを現代化する。
完全分離型SPAでは、認証方式の選択が複雑になる。Cookieベースの認証を使うのか、トークンを使うのか。トークンをどこへ保存するのか。更新期限をどう扱うのか。CORSとCSRFの境界をどう設定するのか。
ネイティブアプリや第三者クライアントが存在するなら、こうした設計は避けられない。しかし、ブラウザだけで完結するアプリケーションに同じ構成を持ち込むと、必要以上に要素が増える。
Inertia.jsでは、LaravelのWebルートに対して認証ミドルウェアを適用し、従来のWebアプリケーションと同じようにアクセスを制御できる。画面側は、認証済みユーザーや権限情報を共有Propsとして受け取り、表示の切り替えに利用する。
ここで注意すべきなのは、表示を隠すことと認可を実施することは別である。ボタンを非表示にしても、サーバー側の認可にはならない。更新や削除などの操作は、Laravelのポリシーやゲートで必ず判定する。
フロントエンドに渡された権限情報は、画面表示を整えるための情報である。セキュリティ境界ではない。
実装コストを比較する
Inertia.jsと完全分離型SPAの違いを、開発工程ごとに整理すると次のようになる。
| 比較項目 | Inertia.js構成 | 完全分離型SPA |
|---|---|---|
| ルーティング | Laravelのルートを中心に管理 | フロントエンドルーターとAPIルートを分離 |
| データ取得 | コントローラーからPropsを渡す | APIを呼び出してデータを取得 |
| 認証 | LaravelのWeb認証を利用しやすい | Cookie、トークン、CORSなどを個別設計 |
| バリデーション | Laravelの標準機能を活用しやすい | APIエラーをフロントエンドで変換 |
| 初期開発 | 構成が小さく、画面追加が速い | 通信層と契約定義の設計が必要 |
| 複数クライアント | Web中心。追加クライアントには不向き | Web、モバイル、外部サービスに展開しやすい |
| デプロイ | Laravelとフロントエンドを一体運用しやすい | サーバー、API、フロントエンドを分離可能 |
| API契約 | 独立したAPI契約は持たない | OpenAPIやスキーマ管理を導入しやすい |
| 長期拡張 | Webアプリの範囲では保守しやすい | クライアント増加時の拡張性が高い |
| 運用上の主な負荷 | Props設計とページ状態の管理 | API互換性、認証、通信エラーの管理 |
この表で見るべきなのは、優劣ではなく、追加される責務である。
完全分離型SPAは、複数クライアントを支えるための境界を明確にできる。その代わり、API設計とフロントエンド通信の責務が増える。Inertia.jsはWebアプリケーションを短く構築できる。その代わり、独立したAPIとして再利用する前提には向かない。
Inertia.jsを選ぶべきケース
次の条件が多いなら、Inertia.jsの採用が合理的である。
1. 主な利用者がブラウザユーザーである
管理画面、予約管理、顧客管理、社内ツールなど、Web画面が中心ならAPIを独立させる理由は小さい。
2. Laravelの認証と認可をそのまま使いたい
セッション認証や既存のミドルウェア構成を維持できるため、認証基盤の作り直しを避けられる。
3. 個人開発で初期実装を短くしたい
API、CORS、スキーマ、通信クライアントの数を減らせる。実装対象が減るため、動作確認の範囲も小さくなる。
4. 画面遷移はSPA風であれば十分である
すべてのデータをクライアントへ保持する必要がなく、Laravel側でページ単位のデータ取得を行える。
5. フロントエンドの表現力を高めたい
Bladeだけでは複雑になりやすいインタラクションを、VueやReactのコンポーネントとして整理できる。
特に、ログイン後のダッシュボードや管理画面では効果が大きい。ページ単位のデータ取得とフォーム処理はLaravelに残し、入力補助や画面内のインタラクションだけをJavaScriptへ寄せる構成が取りやすい。
Inertia.jsのメリットが薄くなるケース
反対に、次の条件ではInertia.jsを選ぶ根拠が弱くなる。
- iOSやAndroidのネイティブアプリが同じデータを利用する
- 外部企業や第三者へAPIを公開する
- 複数のWebクライアントを別々のチームが開発する
- フロントエンドを独立したデプロイ単位で運用する
- APIのバージョン管理とスキーマ契約が必要である
- オフライン対応やクライアント側キャッシュが中心になる
- Laravel以外のバックエンドやサービスも同じAPIを利用する
この場合は、REST APIまたはGraphQLを中心に設計した方がよい。Inertia.jsを無理に採用すると、後から独立APIを追加することになる。
そのとき問題になるのは、コントローラーの再利用ではない。Web画面向けに設計されたProps、認証処理、ページ単位のレスポンス、画面固有の条件分岐が、APIの責務と混ざることである。
完全分離型SPAへ進む判断
完全分離型SPAを選ぶときは、単にReactやVueを使いたいという理由では不十分である。フロントエンドをLaravelから独立させる必要があるかを判断する。
APIを先に設計すべきなのは、データが画面よりも長く生きる場合である。
たとえば、同じ注文情報を管理画面、顧客向けWeb、モバイルアプリ、外部連携サービスが利用するなら、画面に依存しないデータ契約が必要になる。APIはその契約を提供する境界である。
一方、管理画面だけで利用する集計結果や、特定ページ専用の表示用データをAPIとして切り出すと、汎用性のないエンドポイントが増える。画面とデータの関係が一対一に近いなら、Inertia.jsのPropsで十分な可能性が高い。
RESTとGraphQLの選択
完全分離型SPAでも、RESTとGraphQLは用途が異なる。
RESTは、リソース単位のURLとHTTPメソッドで構成しやすい。Laravelの既存機能やAPIリソースとも対応させやすく、個人開発で導入する場合の理解コストが低い。
GraphQLは、クライアントが必要なフィールドを指定できる。複数の画面が異なるデータ形状を要求する場合や、関連データを一つの問い合わせで取得したい場合に有効である。
ただし、GraphQLを採用すれば通信が単純になるわけではない。スキーマ設計、認可、クエリの計算量、過剰取得や深いネストへの対策が必要になる。小規模なLaravelアプリケーションでは、問題の規模に対して構成が大きくなる可能性がある。
API設計では、技術名ではなくクライアント数とデータ契約の寿命を見るべきである。
Inertia.jsで起きやすい設計上の問題
Inertia.jsは構成を小さくできる。しかし、設計上の問題を消すわけではない。
ページPropsが肥大化する
最初は便利でも、コントローラーから多くのデータを渡し始めると、ページPropsが巨大になる。コンポーネントが不要なデータまで受け取り、画面の一部を変更するだけでレスポンス全体の設計に影響する。
対策は、画面単位でPropsを定義することである。データベースのモデルをそのまま渡さず、表示用の構造へ変換する。関連データも必要な範囲に限定する。
共有Propsに何でも入れる
ログインユーザー、通知、権限情報など、複数ページで使うデータは共有Propsに置ける。しかし、共有Propsはすべてのページへ影響する。
重い集計結果やページ固有の設定まで共有すると、全ページのレスポンスサイズが増える。共有すべき情報は、認証ユーザーやフラッシュメッセージのように、アプリケーション全体で意味を持つものに限定する方がよい。
サーバー状態とクライアント状態が混ざる
ページPropsはサーバーから取得した状態である。入力中の値、開閉状態、選択中のタブはクライアント状態である。
この二つを同じオブジェクトへ詰め込むと、再訪問時やページ遷移時の挙動が不明確になる。サーバー状態は再取得される前提で扱い、クライアント状態は必要な範囲で保持する設計が必要である。
APIがないことを利点にしすぎる
APIエンドポイントが不要になることは、初期開発では利点である。しかし、将来の外部連携まで不要になるわけではない。
公開APIが必要になる可能性が高いサービスでは、最初からドメインロジックと画面レスポンスの変換処理を分けておくべきである。Inertia.jsを使う場合でも、業務ルールをコントローラーへ直接書かないことが重要になる。
コントローラーは認証、入力、ユースケース呼び出し、画面への返却に集中させる。将来APIへ移す可能性がある処理をサービス層やアクションへ分離しておけば、移行時の依存関係を抑えられる。
パフォーマンスで見るべき箇所
Inertia.jsの性能を評価するとき、SPAという名称だけで判断するべきではない。ボトルネックは画面遷移方式より、データ取得とレスポンス設計にある。
確認対象は主に次の通りである。
- 初回HTMLとJavaScriptアセットのサイズ
- Inertiaレスポンスに含まれるPropsのサイズ
- 一覧取得時のSQL実行回数
- 関連モデルによるN+1クエリ
- 画面遷移ごとの再取得範囲
- Viteによる開発時と本番時のアセット差
- 大量データを一度に渡していないか
- 画像や添付ファイルをPropsへ含めていないか
たとえば、一覧画面で数千件のレコードをすべてPropsへ渡す設計は、Inertia.jsでも完全分離型SPAでも問題になる。ページネーション、検索条件、必要カラムの限定を行うべきである。
検索画面では、クエリパラメータをLaravel側で処理し、結果をページPropsとして返す構成が扱いやすい。検索条件をすべてブラウザ側に持ち、全件取得後に絞り込む方式は、データ量が増えた時点で破綻する。
計算量の大きい集計も同様である。画面描画の都合で毎回重い集計を実行すると、Inertia.jsの画面遷移が速くてもサーバー側の処理時間がボトルネックになる。
既存Laravelアプリへ導入する場合
新規開発では、Laravel Breezeを使ってInertia.js環境を作りやすい。既存のBladeアプリケーションへ導入する場合は、段階的な移行が適している。
全画面を一度にVueやReactへ移す必要はない。Laravelのルーティングと認証を維持しながら、更新頻度が高い画面や操作が複雑な画面から移行する。
移行対象として検討しやすいのは、次のような画面である。
- フォーム入力が多い管理画面
- 表示内容を頻繁に切り替える検索画面
- 行単位の編集や削除がある一覧
- モーダルやタブを多用する画面
- Bladeの条件分岐が増え、UIの状態管理が難しくなった画面
逆に、静的な案内ページやSEOを最優先する公開ページは、Bladeのまま維持する方が合理的な場合がある。Inertia.jsを全画面へ適用することが目的になると、導入効果が薄い部分までフロントエンド化することになる。
移行時に分けるべき境界
既存画面を移行する際は、次の境界を明確にする。
1. URLとHTTPメソッドはLaravel側に残す
画面をVueやReactへ移しても、認証や認可の責務はLaravelから移さない。
2. データ取得処理と表示処理を分ける
Bladeに埋め込まれたクエリや条件分岐を、そのままコンポーネントへ移植しない。
3. フォームリクエストを再利用する
バリデーションルールをフロントエンドへ複製せず、Laravelを最終的な検証場所にする。
4. 画面専用のデータ変換を定義する
モデルをそのまま返すのではなく、Propsとして必要な形式へ整える。
5. 旧BladeとInertiaページを混在させる
すべてを置き換えるのではなく、画面ごとに移行効果を測定する。
この方法なら、既存システムの認証や業務ロジックを維持しながら、フロントエンドの実装だけを段階的に更新できる。
どちらを選ぶかはクライアントの数で決まる
LaravelとInertia.jsの組み合わせは、Webアプリケーションを短く作るための技術である。API設計、CORS、認証トークン、スキーマ管理を省略できるため、個人開発との相性がよい。
ただし、Inertia.jsが常にSPA構成より優れているわけではない。クライアントが増えるほど、独立APIの価値が高くなる。WebブラウザだけならInertia.js、Webとモバイルを同じデータ基盤で支えるならREST APIまたはGraphQL、という分け方が基本になる。
判断を迷う場合は、次の順番で確認するとよい。
- 利用者はブラウザだけか
- 同じデータを外部クライアントが使うか
- APIの公開やバージョン管理が必要か
- Laravelの認証とルーティングを維持したいか
- フロントエンドを独立デプロイする必要があるか
- 初期開発の速度と将来の拡張性のどちらを優先するか
- データ契約を画面から独立させる必要があるか
この質問に対する回答がWeb中心なら、Inertia.jsを選ぶ理由は十分にある。逆に、将来的に複数クライアントへ展開する計画が具体的なら、初期段階からAPI境界を設計した方が移行コストを抑えられる。
最終的な選択は、フロントエンドの好みではなく、依存関係の置き場所で決まる。
- Inertia.jsは、Laravelのルーティング、認証、バリデーションを維持したままSPA風の画面を構築できる
- APIエンドポイント、CORS、独立した認証基盤を省略できるため、個人開発の初期速度を上げやすい
- Propsの肥大化、状態管理、SQLのボトルネックは別途設計が必要である
- モバイルアプリや第三者向け連携がある場合、独立したREST APIまたはGraphQL APIが必要になる
- Webだけで完結するならInertia.js、複数クライアントを支えるなら完全分離型SPAが適している
- 迷った場合は、SPAという見た目ではなく、データを誰が利用するかで判断するべきである