Laravel8から認証パッケージとしてJetstream, Breezeが登場しフロントエンド側の構築ではInertia.js、 Livewireなど新しい技術が利用されています。今後、Laravelフレームワークの理解を深めるためにはこれらの新しい技術を理解する必要があります。

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

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の基本知識を持っている人を前提に説明しています。

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

Laravelのインストール

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

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


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

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をパッケージで追加することは可能です。

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”を実行して以下の画面が表示されるか確認してください。左上にはLoginとRegisterのリンクが表示されます。

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

ユーザの登録

右上のRegisterのリンクからユーザの登録を行い、Dashboardの画面を表示してください。

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

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


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の文字を変更してみてください。これまで利用していたPHPのbladeファイルではファイルを更新すると即座に変更が反映されていましましたがvueファイルを更新してリロードしても更新内容は反映されません。vueファイルであるため更新させるためにはJavaScriptのビルドが必要なのでnpm run watchコマンドを実行しておく必要があります。


 % npm run watch

実行後に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です。


//略
        "@inertiajs/vue3": "^1.0.0",
        "@tailwindcss/forms": "^0.5.2",
        "@tailwindcss/typography": "^0.5.2",
        "@vitejs/plugin-vue": "^4.5.0",
        "autoprefixer": "^10.4.7",
        "axios": "^1.6.4",
        "laravel-vite-plugin": "^1.0.0",
        "postcss": "^8.4.14",
        "tailwindcss": "^3.1.0",
        "vite": "^5.0.0",
        "vue": "^3.2.31"
    }

Userデータの作成

Inertia.jsの動作確認に利用するためにseeding機能を利用してusersテーブルにダミーデータを登録します。

ダミーデータを入れるためにdatabase¥seeders¥DatabaseSeeder.phpファイルを開いてコメントを外します。


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.0 (PHP 8.3.1 — 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
       //略

Inertia.jsを利用してユーザ一覧を表示

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

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