空の下でひっそりと

てきとーに更新していきます。レーザーカッターや3Dプリンタが好き

Laravel Turboを使ってみた。(NextJSと比較してみる)

Laravel Turbo がいい感じと聞いたので、使ってみました。

claude codeに指示を出しながら軽く触ってみた感じなので、ブログの全般を書いてもらいました。

最後の個人的な感想部分のみ自分で書いています。

環境

  • Laravel 12
  • PHP 8.3
  • PostgreSQL 16
  • Laravel Reverb(WebSocketサーバー)
  • Tailwind CSS (CDN)

Node.jsを使わずに、Laravel Turbo Streamsでリアルタイムな画面更新を実現するチャットアプリケーションを作ってみました。

Laravel Turboの実装でやったこと

基本構成

Room(部屋)とMessage(メッセージ)のシンプルなモデル構成で、/room/{id}でアクセスできるチャット機能。

リアルタイム通信の仕組み

Laravel Turbo Streamsと Laravel Reverbを組み合わせて、以下の流れでリアルタイム更新を実現:

  1. メッセージ送信: フォーム送信でMessageController経由でDBに保存
  2. ブロードキャスト: MessageCreatedイベントをWebSocketで配信
  3. 画面更新: 受信側でTurbo Streamを適用して部分的にDOM更新
// MessageControllerでのブロードキャスト
broadcast(new MessageCreated($message));

// EventクラスでTurbo StreamのHTMLを配信
public function broadcastWith(): array
{
    $html = view('rooms._message', ['m' => $this->message])->render();
    return ['html' => $html];
}

フロントエンド側では、Pusher.jsを使ってWebSocketを受信し、Turbo.renderStreamMessage()でDOM更新を行います。

つまずいたこと・解決方法

1. Laravel Echoのコンストラクタエラー

最初はLaravel EchoライブラリでWebSocket接続を試みましたが、「Echo is not a constructor」エラーが発生。直接Pusher.jsを使用することで解決しました。

2. Pusherバージョン互換性問題

Pusher.js v8系で「cluster must be provided」エラーが発生。Laravel Reverbではclusterが不要なため、v7.6.0にダウングレードして解決。

3. 重複メッセージ表示問題

送信者が自分のメッセージを2回見る問題が発生: - 1回目:フォーム送信の即時表示 - 2回目:WebSocket経由での受信

解決策として、送信者もWebSocket経由でのみメッセージを受信するよう変更。フォーム送信は非同期化し、JSON応答のみ返すようにしました。

// 非同期フォーム送信
document.getElementById('messageForm').addEventListener('submit', async function(e) {
    e.preventDefault();
    const response = await fetch(this.action, {
        method: 'POST',
        body: new FormData(this)
    });
    if (response.ok) {
        messageInput.value = '';
    }
});

Next.jsなどのJSフレームワークとの比較

Laravel Turboの利点

  • 学習コストの低さ: 既存のLaravelスキルで実装可能
  • サーバーサイド主体: ロジックがバックエンドに集約される
  • SEO対応: サーバーサイドレンダリングが標準
  • 軽量: Node.js環境が不要

制約・課題

  • リッチなUI: 複雑なインタラクティブ要素は実装が困難
  • クライアントサイド状態管理: Reactのような状態管理ライブラリがない
  • エコシステム: JavaScriptエコシステムほど豊富ではない

使ってみた感想

個人的にはLaravel Turboかなりいいと感じました。ただ、Reactを使った時はコンポーネントによるUI側の整理などもできるため、システムが大きくなってくるとReact側がいいのかな?と思いました。

一部分だけでbroadcastさせたい時のシステム開発はLaravelだけで足りる可能性がありそうだなと感じたし、開発環境がシンプルになるので、個人的には好きだな〜と思いました。

まとめ

Laravel Turboはとてもいい。