Laravelを利用するメリットの一つに認証機能がデフォルトから実装されていることです。Laravelを使うのが初めての人でも認証機能を利用することができます。Laravel8から認証パッケージとしてJetstream, Breezeが登場しフロントエンド側の構築ではInertia.js、 Livewireなど新しい技術が利用されています。それまではLarave UIというライブラリを追加でインストールしていましたが、Laravelフレームワークの理解を深めるためにはこれらの新しい技術を理解する必要があります。

現行バーションのLaravelでInertia.jsを利用したい場合にLaravel BreezeかLaravel Jetstreamを利用すると簡単に利用を開始することができます。(それらのパッケージを利用しなくてもInertia.jsを個別にインストールして利用することも可能)。本文書の公開当時はLaravel8がリリースされた直後でLaravel Breezeが存在しなかったこともありLaravel Jetstreamを利用してInertia.jsの説明を行っています。
fukidashi

Laravelのバージョン8からInertia.jsが登場し, Vue, Reactを利用してフロントエンドのUIを作成することが可能となりました。Inertia.jsの他にLaravelのバージョン8からLivewireを利用することも可能になりました。LivewireはInertia.jsとは異なりでPHP + Bladeでフロントエンドの開発を行いインタラクティブな機能を追加する場合にはAlpine.jsを利用してアプリケーションを構築することができます。

VueやReactなどJavaScriptによりフロントエンドを作成したい開発者はInertia.js、PHPでバックエンドのLaravelとフロントエンド部分を作成したい開発者はLivewireを利用することになるかと思います。Inertia.jsやLivewireを利用しなくてもBladeを利用した従来の方法でフロントエンド側の画面を作成することは可能です。

本文書はInertia.jsってどんな技術なのか頭の中が??だらけの人を対象にJetStreamパッケージをインストールした環境で手を動かしながらInertia.jsの使い方をシンプルなコードを利用して説明しています。本文書を読んだだけではInertia.jsを利用したアプリケーションを構築することはできませんがInertia.jsがどのようなものかの理解は深まると思います。

Vue.jsのpropsなどVue.jsの基本知識を持っている人を前提に説明しています。

Laravel11, Laravel10, Laravel9, Laravel8で動作確認を行っています。本文書はLaravel11環境で実行した内容に更新しています。

Laravelのインストール

最初にLaraveのインストールを行います。Mac環境でのLaravel10のインストールは下記の文書で公開ずみなので参考にしてください。

Laravel JetstremaでInertia.jsを利用するためにlaravelコマンドでオプションの–jetを使いInertiaの選択を行うことができます。


 % laravel new laravel_jetstream --jet
laravel new –helpで確認すると–jetの他に–stackといったオプションもあり事前にLivewireかinertiaを利用するか指定ることも可能です。
fukidashi

Laravel11の場合

Livewireか”Vue with Inertia”を選択できますが、ここでは”Vue with Inertia”を選択します。


   _                               _
  | |                             | |
  | |     __ _ _ __ __ ___   _____| |
  | |    / _` | '__/ _` \ \ / / _ \ |
  | |___| (_| | | | (_| |\ V /  __/ |
  |______\__,_|_|  \__,_| \_/ \___|_|


 ┌ Which Jetstream stack would you like to install? ────────────┐
 │ › ● Livewire                                                 │
 │   ○ Vue with Inertia                                         │
 └──────────────────────────────────────────────────────────────┘

追加の機能を選択することができますがここでは何も選択しません。


 ┌ Would you like any optional features? ───────────────────────┐
 │ › ◻ API support                                              │
 │   ◻ Dark mode                                                │
 │   ◻ Email verification                                       │
 │   ◻ Team support                                             │
 │   ◻ Inertia SSR                                              │
 └──────────────────────────────────────────────────────────────┘

テストで利用するパッケージを選択できますが”Pest”を選択します。Git repositoryは動作確認なので”No”を選択します。


 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ › ● Pest                                                     │
 │   ○ PHPUnit                                                  │
 └──────────────────────────────────────────────────────────────┘
 ┌ Would you like to initialize a Git repository? ──────────────┐
 │ ○ Yes / ● No                                                 │
 └──────────────────────────────────────────────────────────────┘

Laravel11ではデータベースのの作成までプロジェクトの作成中に行ってくれます。SQLiteを選択します。


 ┌ Which database will your application use? ───────────────────┐
 │   ○ MySQL                                                    │
 │   ○ MariaDB                                                  │
 │   ○ PostgreSQL                                               │
 │ › ● SQLite                                                   │
 │   ○ SQL Server                                               │

プロジェクトの作成が完了したら、プロジェクトディレクトリ(laravel_jetstream)に移動してphp artisan serveコマンドを実行して開発サーバを起動していください。


% php artisan serve

   INFO  Server running on [http://127.0.0.1:8000].  

  Press Ctrl+C to stop the server                                         │

ブラウザからhttp://127.0.0.1:8000にアクセスすると初期ページが表示されます。右上にはLog inとRegisterのリンクが表示されます。

Laravel11初期画面
Laravel11初期画面

Laravel10以前の場合

livewireかinertiaの選択ができますが、ここではinertiaを選択します。


Which Jetstream stack do you prefer?
  [0] livewire
  [1] inertia
 > 1

teamsを利用するかどうか確認がありますが今回は利用しないのでNoを選択します。デフォルトでは”no”の選択になります。


 Will your application use teams? (yes/no) [no]:
 > no
Laravelインストール後にJestreamをパッケージで追加することは可能です。
fukidashi

JetsteamのインストールではJavaScriptのライブラリのインストールとコンパイルを行うため作成されるプロジェクトフォルダに移動します。


% cd laravel_jetstream 

php artisan serveコマンドを実行して開発サーバのhttp://127.0.0.1:8000にアクセスするとデータベースが存在しないために下記のエラー画面が表示されます。

接続時のエラーメッセージ
接続時のエラーメッセージ

Laravelにアクセスするためにはデータベースが必要になるのでデータベースの準備をしてください。本文書ではSQLiteを利用してデータベースを作成しています。

.envファイルでDB_CONNECTIONをsqliteに変更し、その他のDBに関連する環境変数を削除します。削除する環境変数うは先頭にDB_がついているものです。


DB_CONNECTION=sqlite

これでデータベースの設定が完了できたので、php artisan migrateコマンドを実行してください。SQLiteはファイルベースのデータベースなのでファイルが存在しない場合には警告が表示され、ファイルを作成するか聞かれるので”Yes”を選択します。実行が完了すると6つのテーブルが作成されます。


 % php artisan migrate

   WARN  The SQLite database does not exist: database/database.sqlite.  

 ┌ Would you like to create it? ────────────────────────────────┐
 │ Yes                                                          │
 └──────────────────────────────────────────────────────────────┘

   INFO  Preparing database.  

  Creating migration table ................................. 8ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table ...................... 3ms DONE
  2014_10_12_100000_create_password_reset_tokens_table ...... 1ms DONE
  2014_10_12_200000_add_two_factor_columns_to_users_table ... 3ms DONE
  2019_08_19_000000_create_failed_jobs_table ................ 2ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ..... 3ms DONE
  2024_01_17_041021_create_sessions_table ................... 2ms DONE

データベース作成後に”php artisan migrate”を実行して以下の画面が表示されるか確認してください。右上にはLog inとRegisterのリンクが表示されます。

Laravel10のトップ画面
Laravel10のトップ画面

Dashboardページの更新

右上のRegisterのリンクからユーザの登録を行うことDashboardの画面が表示されます。

Laravel Jetstream ダッシュボード画面
Laravel Jetstream ダッシュボード画面

このDashboardの画面がどのように表示されるかを確認するためweb.phpファイルを開きます。Inertia\Inertia::renderを確認することができます。


use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;

Route::get('/', function () {
    return Inertia::render('Welcome', [
        'canLogin' => Route::has('login'),
        'canRegister' => Route::has('register'),
        'laravelVersion' => Application::VERSION,
        'phpVersion' => PHP_VERSION,
    ]);
});

Route::middleware([
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified',
])->group(function () {
    Route::get('/dashboard', function () {
        return Inertia::render('Dashboard');
    })->name('dashboard');
});

Inertia::render関数の引数に指定しているDashboardはresources¥viewsディレクトリの中ではなくresources¥js¥Pagesの下にあるDashboard.vueファイルです。bladeファイルではなくvueファイルなのもポイントです。

本当にDashboard.vueファイルの内容がブラウザ上に表示されているのか確認するために”Dashboard”の文字列を変更してみてください。ここでは”Dashboard Inertis”に変更します。bladeファイルではファイルを更新してブラウザを再読み込みすると変更が反映されましたがvueファイルを更新してリロードしても更新内容は反映されません。vueファイルであるため更新させるためにはJavaScriptのビルドが必要なので”npm run dev”コマンドを実行しておく必要があります。


npm run dev

> dev
> vite


  VITE v5.3.5  ready in 498 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

  LARAVEL v11.19.0  plugin v1.0.5

  ➜  APP_URL: http://localhost
コマンドはpackage.jsonファイルのscriptsに登録されています。
fukidashi

実行後にDashboard.vueファイルを下記のように変更するとブラウザにも変更が反映されます。Dashboardという文字列にInertiaを追加しています。


<template>
    <app-layout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Dashboard Inertia
            </h2>

Dashboardの文字列にInertiaの文字列が追加されたので間違いなくweb.phpファイルで指定されているDashboardがこのresources¥js¥PagesにあるDashboard.vueファイルであることがわかります。

表示される内容が変わる
表示される内容が変わる

ここまでの動作確認で拡張子vueを持つファイルを利用しているのでJetstreamでInertia.jsを選択した場合にはVue.jsを利用していることは間違いないということがわかったかと思います。インストールされているVue.jsのバージョンを確認したい場合にはpackage.jsonファイルで確認することができます。vueのバージョンは3.2.31です。


{
    "private": true,
    "type": "module",
    "scripts": {
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "@inertiajs/vue3": "^1.0.14",
        "@tailwindcss/forms": "^0.5.7",
        "@tailwindcss/typography": "^0.5.10",
        "@vitejs/plugin-vue": "^5.0.0",
        "autoprefixer": "^10.4.16",
        "axios": "^1.6.4",
        "laravel-vite-plugin": "^1.0",
        "postcss": "^8.4.32",
        "tailwindcss": "^3.4.0",
        "vite": "^5.0",
        "vue": "^3.3.13"
    }
}

Inertia.jsの動作確認

Dashboard.vueファイルの文字列を更新できることがわかったので、次はシンプルな例を通してInertia.jsの動作確認を行います。デフォルトでデータベースに作成済みのusersテーブルを利用します。

Userデータの作成

ユーザ登録画面から1名分のユーザを登録しましたが一括でusersテーブルにユーザ情報を登録できるようにseeding機能を利用してダミーデータを登録します。

ダミーデータを入れるためにdatabase¥seeders¥DatabaseSeeder.phpファイルを開いてコメントを外して10名分のユーザを登録できるに変更します。


namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        \App\Models\User::factory(10)->create();

        // \App\Models\User::factory()->create([
        //     'name' => 'Test User',
        //     'email' => 'test@example.com',
        // ]);
    }
}

php artisan db:seedコマンドを実行します。


 % php artisan db:seed

   INFO  Seeding database.  

データの準備は完了です。データが登録されているかはTablePlusなどのGUIのアプリケーションを利用するか直接データベースへの接続またはphp artisan tinkerを利用してください。


% php artisan tinker
Psy Shell v0.12.4 (PHP 8.3.8 — cli) by Justin Hileman
> User::all();
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
=> Illuminate\Database\Eloquent\Collection {#4562
     all: [
       App\Models\User {#4564
       //略

ユーザ一覧を表示

Userコントローラーを作成

php artisan make:controllerコマンドでUser用のコントローラーを作成します。


% php artisan make:controller UserController
   INFO  Controller [app/Http/Controllers/UserController.php] created successfully. 

ルーティングを追加

web.phpファイルにルーティング/userを追加し、UserControllerを指定します。


Route::resource('/user','App\Http\Controllers\UserController');

User/Index.vueファイルを作成

ルーティングの追加が完了したのでUserController.phpファイルを更新します。Inertia::renderを使ってUser/Indexを指定します。これはDashboardの時に説明しましたがbladeファイルではなくvueファイルでresource/js/Pages以下のUser/Indexを指しています。そのファイルにUser:all()でusersテーブルのユーザ情報をusersという名前で渡しています。


namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Inertia\Inertia;

class UserController extends Controller
{

    public function index()
    {

        return Inertia::render('User/Index',['users' => User::all()]);
        
    }

}

resource/js/Pagesの下にはUser/Index.vueファイルは存在しないので作成を行います。Inertiaのrender関数で渡していたusersはvueファイルにpropsとして渡すことができます。

これまでLaravelのvueファイル内でユーザ一覧を取得して使用とした場合は大まかに以下のような処理を行う必要がありました。

  1. api.phpファイルにルーティングを追加
  2. vueファイルのライフサイクルフック内でaxios, fetchのgetメソッドで追加したルーティングにアクセス
  3. 取得したデータをvueのデータプロパティに保存

しかし、Inertia.jsを利用すると上記のような手間をかける必要がなくUserController.phpで取得したユーザ一覧のデータusersをpropsとしてIndex.vueファイルに渡すことができます。

vueファイルでの処理

vueファイル内ではpropsとしてusersを受け取ることができるので追加の設定や処理は必要ありません。

propsで受け取ったusersをtemplateタグで展開することでブラウザに表示させることができます。Vueのバージョン3からComposition APIのscript setupタグを利用することができます。


<script setup>
defineProps({ users: Array });
</script>
<template>
    <div class="p-4">
        <h1 class="text-lg font-bold">ユーザ一覧</h1>
        <ul>
            <li v-for="user in users" :key="user.id">{{ user.name }}</li>
        </ul>
    </div>
</template>
ユーザ一覧を表示
ユーザ一覧を表示

ユーザ一覧を表示するというシンプルな例でしたが、inertiaを利用することでバックエンドからのデータ取得の処理が大幅に楽になったことがわかるのではないでしょうか。

Vue3でもOptions APIを利用して記述することができます。Options APIで記述すると以下となります。


<template>
    <div class="p-4">
        <h1 class="text-lg font-bold">ユーザ一覧</h1>
        <ul>
            <li v-for="user in users" :key="user.id">{{ user.name }}</li>
        </ul>
    </div>
</template>
<script>
export default {
    props: {
        users: {
            type: Array,
        },
    },
};
</script>

dashboardへのリンク設定

dashboardへのリンクを設定したい場合は、aタグではなくLinkタグを利用することができます。Linkタグを利用するためにはimportが必要となります。


<script setup>
import { Link } from "@inertiajs/vue3";
defineProps({
    users: Array,
});
</script>
<template>
    <header>
        <ul>
            <li><Link href="/dashboard">Dashboard</Link></li>
        </ul>
    </header>

    <div class="p-4">
        <h1 class="text-lg font-bold">ユーザ一覧</h1>
        <ul>
            <li v-for="user in users" :key="user.id">{{ user.name }}</li>
        </ul>
    </div>
</template>

Linkを使用するとページをリロードすることなくdashboardの内容が画面に表示されます。ユーザのログインが完了している状態で行ってください。

aタグの場合はページを移動する場合にはページ全体を読み込む必要がありますがLinkタグを利用している場合は更新が必要な箇所のみJavaScript(Vue)によって更新が行われるためページの移動をスムーズに行うことができます。

まとめ

非常に短い文書でしたが本文書から以下のことが理解できました。

  • Laravel8, 9, 10, 11ではJetStreamパッケージを利用することでInertia.jsの特別な設定を行うことなくすぐに利用できる
  • JetStream環境下のInertia.jsを利用する場合にはVueを使ってブラウザに表示する画面を作成する
  • vueファイルで利用するデータはLaravelの従来の方法と同じ方法でデータを取得してVue.jsにはpropsを経由して渡す
  • Bladeファイルとは異なりVueファイルはJavaScriptなので内容を更新するとJavaScriptのビルドが必要
  • Linkタグを利用することでページの移動をスムーズに行うことができる

本文書の内容だけではInertia.jsが何者かということは少しは理解できたと思います。下記の文章ではinertiaを利用してCRUD処理を説明しているのでさらに理解を深めたい場合はおすすめです。