サーバーサイドレンダリング(SSR)

サーバーサイドレンダリングは、サーバー上で JavaScript ページを事前にレンダリングし、訪問者がアプリケーションにアクセスした際に、完全にレンダリングされた HTML を受け取れるようにします。完全にレンダリングされた HTML がアプリケーションから提供されるため、検索エンジンによるサイトのインデックス化も容易になります。

サーバーサイドレンダリングでは、バックグラウンドプロセスで Node.js を使用してページをレンダリングします。そのため、サーバーサイドレンダリングを正しく動作させるには、サーバー上で Node が利用可能である必要があります。

Laravel スターターキット

Laravel スターターキット を使用している場合、Inertia SSR はビルドコマンドを通じて サポート されています。

bash
npm run build:ssr

依存関係のインストール

Laravel スターターキットを使用しておらず、SSR を手動で設定したい場合は、まずサーバーサイドレンダリングに必要な追加の依存関係をインストールします。これは Vue アダプターのみで必要となるため、React や Svelte を使用している場合はこの手順をスキップできます。

サーバーエントリーポイントの追加

次に、Laravel プロジェクト内に resources/js/ssr.js ファイルを作成し、これを SSR のエントリーポイントとして使用します。

bash
touch resources/js/ssr.js

このファイルは resources/js/app.js ファイルと非常によく似ていますが、ブラウザではなく Node.js 上で実行される点が異なります。以下は完全な例です。

このファイルを作成する際は、SSR モードで実行するのに適した、app.js ファイルに含まれているが不足しているもの(プラグインやカスタムミックスインなど)があれば追加してください。

クラスタリング

デフォルトでは、SSR サーバーは単一スレッドで実行されます。クラスタリングを有効にすると、同じポート上で複数の Node サーバーが起動され、リクエストはラウンドロビン方式で各スレッドによって処理されます。

createServer に第 2 引数としてオプションを渡すことで、クラスタリングを有効にできます。

Vite のセットアップ

次に、新しく作成した ssr.js ファイルをビルドするために、Vite の設定を更新します。vite.config.js ファイル内の Laravel の Vite プラグイン設定に ssr プロパティを追加します。

vite.config.js
export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            ssr: 'resources/js/ssr.js', // [!code ++]
            refresh: true,
        }),
        // ...
    ],
})

NPM スクリプトの更新

次に、package.json ファイル内の build スクリプトを更新し、新しい ssr.js ファイルもビルドされるようにします。

package.json
"scripts": {
    "dev": "vite",
   "build": "vite build" // [!code --]
   "build": "vite build && vite build --ssr" // [!code ++]
},

これで、クライアントサイドおよびサーバーサイドの両方のバンドルをビルドできます。

bash
npm run build

SSR サーバーの実行

クライアントサイドとサーバーサイドの両方のバンドルをビルドしたら、次のコマンドを使用して Node ベースの Inertia SSR サーバーを実行できます。

bash
php artisan inertia:start-ssr

--runtime オプションを使用して、利用するランタイムを指定することもできます。これにより、デフォルトの Node.js ランタイムから Bun に切り替えることができます。

bash
php artisan inertia:start-ssr --runtime=bun

サーバーが起動すると、サーバーサイドレンダリングが有効な状態でブラウザからアプリにアクセスできるようになります。実際、JavaScript を完全に無効にしても、アプリケーション内を移動できるはずです。

クライアントサイドハイドレーション

ウェブサイトがサーバーサイドレンダリングされるようになったため、VueReactSvelte に対して、生成されたすべての HTML を再レンダリングする代わりに、静的マークアップを「ハイドレート」してインタラクティブにするよう指示できます。

Vue アプリでクライアントサイドハイドレーションを有効にするには、ssr.js ファイルで createApp の代わりに createSSRApp を使用するよう更新してください。

React アプリでクライアントサイドハイドレーションを有効にするには、ssr.js ファイルで createRoot の代わりに hydrateRoot を使用するよう更新してください。

Svelte 4 アプリでクライアントサイドハイドレーションを有効にするには、ssr.js ファイルで hydrate オプションを true に設定してください。

Svelte 5 アプリでクライアントサイドハイドレーションを有効にするには、サーバーレンダリング時に mount の代わりに hydrate を使用するよう ssr.js ファイルを更新してください。

また、vite.config.js ファイルで hydratable コンパイラオプションを true に設定する必要があります。

vite.config.js
import { svelte } from '@sveltejs/vite-plugin-svelte'
import laravel from 'laravel-vite-plugin'
import { defineConfig } from 'vite'

export default defineConfig({
    plugins: [
        laravel.default({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            ssr: 'resources/js/ssr.js',
            refresh: true,
        }),
        svelte(), // [!code --]
        svelte({ // [!code ++:5]
            compilerOptions: {
                hydratable: true,
            },
        }),
    ],
})

SSR の無効化

場合によっては、アプリケーション内の特定のページやルートでサーバーサイドレンダリングを無効にしたいことがあります。その場合、現在のリクエストに対して inertia.ssr.enabled 設定値を false に設定します。通常はサービスプロバイダやミドルウェア内で行います。

php
if (request()->is('admin/*')) {
    config(['inertia.ssr.enabled' => false]);
}

デプロイ

SSR を有効にしたアプリを本番環境にデプロイする際は、クライアントサイド(app.js)とサーバーサイド(ssr.js)の両方のバンドルをビルドし、その後、Supervisor などのプロセス監視ツールを使用して SSR サーバーをバックグラウンドプロセスとして実行する必要があります。

bash
php artisan inertia:start-ssr

新しいバージョンのウェブサイトをデプロイする際などに SSR サーバーを停止するには、inertia:stop-ssr Artisan コマンドを使用できます。プロセスモニター(Supervisor など)が、停止後に SSR サーバーを自動的に再起動する役割を担う必要があります。

bash
php artisan inertia:stop-ssr

inertia:check-ssr Artisan コマンドを使用すると、SSR サーバーが稼働していることを確認できます。これはデプロイ後に役立ち、Docker のヘルスチェックとしても、サーバーが期待どおりに応答していることを確認するのに有効です。

bash
php artisan inertia:check-ssr

デフォルトでは、SSR サーバーにリクエストを送信する前に、サーバーサイドバンドルが存在することを確認するチェックが行われます。アプリが複数のサーバーで実行されている場合や、コンテナ化されている場合など、ウェブサーバーが SSR バンドルにアクセスできないケースでは、このチェックを無効にするために inertia.ssr.ensure_bundle_exists 設定値を false に設定できます。

Laravel Cloud

Laravel Cloud で SSR サーバーを実行するには、Cloud の Inertia SSR ネイティブサポート を使用できます。

Laravel Forge

Forge で SSR サーバーを実行するには、アプリのルートディレクトリから php artisan inertia:start-ssr を実行する新しいデーモンを作成してください。または、Forge アプリケーションの管理ダッシュボードにある組み込みの Inertia 連携を利用することもできます。

以降、アプリケーションをデプロイするたびに php artisan inertia:stop-ssr コマンドを呼び出すことで、SSR サーバーを自動的に再起動できます。これにより、既存の SSR サーバーが停止され、プロセスモニターによって新しいサーバーが起動されます。

Heroku

Heroku で SSR サーバーを実行するには、Procfileweb 設定を更新し、ウェブサーバーを起動する前に SSR サーバーを実行するようにします。

bash
web: php artisan inertia:start-ssr & vendor/bin/heroku-php-apache2 public/

なお、SSR サーバーを実行するには、heroku/php ビルドパックに加えて heroku/nodejs ビルドパックがインストールされている必要があります。