Laravel プロジェクトで Inertia.js を使用する方法

公開: 2022-12-08

マルチページ アプリケーション (MPA) は、日に日に人気が低下しています。 Facebook、Twitter、YouTube、Github などの有名なプラットフォームや、その他多くのプラットフォームでは、代わりにシングルページ アプリケーション (SPA) テクノロジが既に使用されています。

このトレンディなテクノロジにより、すべてがクライアント側でレンダリングされるため、ユーザーは Web アプリケーションを迅速かつ応答的に操作できます。 ただし、Laravel や Django などのフレームワークを使用してサーバー側でレンダリングされたアプリケーションを構築する開発者にとっては、面倒な作業になる可能性があります。

幸いなことに、Inertia.js が介入して救助に来ました。
Laravel プロジェクトに必要な不足している要素はありますか? Inertia.js. 詳細については、この完全なガイドをご覧ください。 クリックしてツイートしてください。
この記事では、Inertia.js の使用を開始する方法と、それを Laravel、Vue.js、Tailwind CSS で使用して最新のブログ Web アプリを作成する方法を示します。 また、SPA をより SEO フレンドリーにする方法や、その他のいくつかのトリックも紹介します。

Laravel を使い始めたばかりの場合は、まずこの記事を読んで準備を整えることをお勧めします。

なぜスパ?

Inertia を使用する理由を尋ねる前に、「なぜ SPA なのか?」と尋ねる必要があります。

従来のサーバー側アプリケーションよりも、クライアント側でレンダリングされたアプリケーションを好む人がいるでしょうか? フルスタックの Laravel 開発者がブレード コンポーネントに別れを告げるにはどうすればよいでしょうか?

簡単に言えば、ユーザー エンゲージメントを成功させるには速度と応答性が不可欠だからです。

MPA の場合、ブラウザーは常に要求をバックエンドに送信し、バックエンドは多数のデータベース クエリを実行します。 データベースとサーバーがクエリを処理してブラウザに配信した後、ページがレンダリングされます。

しかしSPAは違います。 このアプリケーションは、ユーザーが必要とするすべてのものをページに直接表示するため、ブラウザーがクエリを送信したり、ページをリロードして新しい HTML 要素をレンダリングしたりする必要がなくなります。

この他に類を見ないユーザー エクスペリエンスのために、多くの大手企業は自社の Web サイトを単一ページのアプリケーションにすることを強く求めています。

そうは言っても、単一ページのアプリケーションを作成することは、ブレード テンプレートの代わりに Vue.js または React の使用を開始する必要があり、時間と労力を節約する多くの Laravel gem が失われるため、Laravel 開発者にとって難しい場合があります。

しかし、Inertia.js ができたので、すべてが変わりました。

なぜ慣性?

Laravel 開発者が Inertia の前に Vue で Web SPA を構築する場合、API をセットアップして Laravel で JSON データを返し、AXIOS などを使用して Vue コンポーネントでデータを取得する必要があります。 また、ルートを管理するために Vue Router のようなものが必要になります。これは、Laravel ルーティング、ミドルウェア、コントローラーを失うことを意味します。

一方、Inertia.js を使用すると、開発者は従来のサーバー側のルーティングとコントローラーを使用して、最新の単一ページの Vue、React、および Svelte アプリを構築できます。 Inertia は、Laravel、Ruby on Rails、および Django の開発者向けに設計されており、コントローラーの作成、データベースからのデータのフェッチ、およびビューのレンダリングのコーディング手法を変更せずにアプリを構築できるようにします。

Inertia.js のおかげで、Laravel 開発者は自宅にいるように感じることができます。

慣性のしくみ

Laravel と Vue のみを使用して SPA を構築すると、フロントエンド用の完全な JavaScript ページが提供されますが、単一ページのアプリ エクスペリエンスは提供されません。 リンクをクリックするたびに、次のページの読み込み時にクライアント側フレームワークが再起動します。

ここで慣性が登場します。

Inertia は、基本的にクライアント側のルーティング ライブラリです。 ページ全体をリロードしなくても、ページ間を移動できます。 これは、標準アンカー タグの軽量ラッパーである<Link>コンポーネントを介して実現されます。

Inertia リンクをクリックすると、Inertia はクリックをインターセプトし、代わりに XHR にリダイレクトします。 ブラウザはこの方法でページをリロードしないため、ユーザーは完全なシングルページ エクスペリエンスを利用できます。

慣性を使い始める

上部の青いバナーに「Kinsta ブログ」と表示され、サンプル記事カードが 1 列に並んだシンプルなページ。
Inertia.jsで作ったサンプルページ

Inertia とそれを Laravel と統合する方法を理解するために、バックエンドに Laravel、JavaScript フロントエンドに Vue.js、スタイリングに Tailwind CSS という最も強力な組み合わせを使用して、 Kinsta ブログという名前のブログ Web アプリを作成します。

このチュートリアルをローカル環境で実行したい場合は、開発者、デザイナー、代理店向けの強力なツールである DevKinsta を使用して、単一ページおよび複数ページの WordPress Web アプリを構築できます。 幸いなことに、Corcel パッケージを使用して WordPress を Laravel と簡単に統合できます。

前提条件

このチュートリアルを最大限に活用するには、次のことを理解しておく必要があります。

  • Laravel の基本 (インストール、データベース、データベースの移行、Eloquent モデル、コントローラー、およびルーティング)
  • Vue.js の基本 (インストール、構造、およびフォーム)

確信が持てない場合は、これらの素晴らしい Laravel の無料および有料のチュートリアルをチェックしてください。 それ以外の場合は、飛び込みましょう。

ステップ 1: コア要素をインストールする

Inertia.js に集中してすぐに楽しい部分に取り掛かるには、次のセットアップが準備されていることを確認してください。

  1. kinsta-blogという名前の新しくインストールされたLaravel 9プロジェクト
  2. Laravel プロジェクトにインストールされた Tailwind CSS CLI
  3. 以下に示すように、ブログのホームページとブログの単一の記事を表示するためのkinsta-blog/resources/viewsの 2 つのブレード コンポーネント:

    /resources/views/index.blade.php “:

     <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Kinsta Blog</title> </head> <body> <header> <h1>Kinsta Blog</h1> </header> <main> <h2>Read our latest articles</h2> <section> <article> <div> <img src="/images/kinsta-logo.png" alt="Article thumbnail" /> </div> <h3>Title for the blog</h3> <p> Lorem, ipsum dolor sit amet consectetur adipisicing elit. Illum rem itaque error vel perferendis aliquam numquam dignissimos, expedita perspiciatis consectetur! </p> <a href="#">Read more</a> </article> </section> </main> <footer> <h2>Join our Newsletter</h2> <input type="email" /> </footer> </body> </html>

    /resources/views/show.blade.php “:

     <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Kinsta Blog</title> </head> <body> <main> <article> <div> <img src="/images/kinsta-logo.png" alt="Article thumbnail" /> </div> <h1>Title for the blog</h1> <p>Article content goes here</p> </article> </main> <footer> <h2>Join our Newsletter</h2> <input type="email" /> </footer> </body> </html>
  4. プロジェクトに接続されたkinsta_blogという名前の MySQL ローカル データベース:

    .env 」:

     DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=kinsta_blog DB_USERNAME=root DB_PASSWORD=
  5. 記事のモデル、移行、工場:

    “アプリ/モデル/ Article.php “:

     <?php namespace AppModels; use IlluminateDatabaseEloquentFactoriesHasFactory; use IlluminateDatabaseEloquentModel; class Article extends Model { use HasFactory; protected $fillable = ['title', 'excerpt', 'body']; }

    “データベース/移行/ create_articles_table.php “:

     <?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; return new class extends Migration { public function up() { Schema::create('articles', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('excerpt'); $table->text('body'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('articles'); } };

    “データベース/工場/ ArticleFactory.php “:

     <?php namespace DatabaseFactories; use IlluminateDatabaseEloquentFactoriesFactory; class ArticleFactory extends Factory { public function definition() { return [ 'title' => $this->faker->sentence(6), 'excerpt' => $this->faker->paragraph(4), 'body' => $this->faker->paragraph(15), ]; } }

始めるために必要なのはこれだけです。 それでは、本題に取り掛かり、プロジェクトに Inertia.js を導入しましょう。

ステップ 2: 慣性をインストールする

Inertia のインストール プロセスは、サーバー側 (Laravel) とクライアント側 (VueJ) の 2 つの主要なフェーズに分かれています。

Inertia ドキュメントの公式インストール ガイドは、Laravel 9 がデフォルトで Vite を使用するようになったため、少し古くなっていますが、それについても説明します。

1. サーバー側

最初に行う必要があるのは、Composer を介して以下の端末コマンドを使用して Inertia サーバー側アダプターをインストールすることです。

 composer require inertiajs/inertia-laravel

次に、ルート テンプレートを設定します。これは、CSS および JS ファイルをロードするために使用される単一のブレード ファイルと、JavaScript アプリケーションを起動するために使用される慣性ルートです。

最新バージョンの Laravel 9 v9.3.1 を使用しているため、 /resources/views/ app.blade.phpのタグ内に Vite を含めることで、Vite が魔法を働かせるようにする必要があります。

 <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <!-- Fetch project name dynamically --> <title inertia>{{ config('app.name', 'Laravel') }}</title> <!-- Scripts --> @vite('resources/js/app.js') @inertiaHead </head> <body class="font-sans antialiased"> @inertia </body> </html>

<title>タグにInertia属性を追加することで、プロジェクトのタイトルを動的に取得できることに注目してください。

また、アプリを作成して CSS をインポートした JavaScript メイン ファイルのパスを Vite に知らせるために、 @viteディレクティブをヘッドに追加しました。 Vite は、開発者がローカル開発中にページを更新することなくフロントエンドの変更を表示できるようにすることで、JavaScript および CSS 開発を支援するツールです。

次のステップは、 HandleInertiaRequestsミドルウェアを作成し、それをプロジェクトに公開することです。 これを行うには、プロジェクトのルート ディレクトリ内で以下の端末コマンドを実行します。

 php artisan inertia:middleware

これが完了したら、「App/Http/ Kernel 」に進み、 HandleInertiaRequestsを Web ミドルウェアの最後の項目として登録します。

 'web' => [ // ... AppHttpMiddlewareHandleInertiaRequests::class, ],

2. クライアント側

次に、フロントエンドの Vue.js 3 依存関係をサーバー側と同じ方法でインストールする必要があります。

 npm install @inertiajs/inertia @inertiajs/inertia-vue3 // or yarn add @inertiajs/inertia @inertiajs/inertia-vue3

次に、Vue.js 3 をプルする必要があります。

 npm install [email protected]

次に、プライマリ JavaScript ファイルを更新して、Vue.js 3、Vite、および Laravel で Inertia.js を初期化します。

“resources/js/ app.js ”:

 import "./bootstrap"; import "../css/app.css"; import { createApp, h } from "vue"; import { createInertiaApp } from "@inertiajs/inertia-vue3"; import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers"; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => resolvePageComponent( `./Pages/${name}.vue`, import.meta.glob("./Pages/**/*.vue") ), setup({ el, app, props, plugin }) { return createApp({ render: () => h(app, props) }) .use(plugin) .mount(el); }, });

上記のコード スニペットでは、Laravel のプラグインresolvePageComponentを使用し、ディレクトリ./Pages/$name.vueからコンポーネントを解決するように指示しています。 これは、プロジェクトの後半で Inertia コンポーネントをこのディレクトリに保存するためです。このプラグインは、これらのコンポーネントを正しいディレクトリから自動的にロードするのに役立ちます。

あとはvitejs/plugin-vueをインストールするだけです:

 npm i @vitejs/plugin-vue

vite.config.jsファイルを更新します。

 import { defineConfig } from "vite"; import laravel from "laravel-vite-plugin"; import vue from "@vitejs/plugin-vue"; export default defineConfig({ plugins: [ laravel({ input: ["resources/css/app.css", "resources/js/app.js"], refresh: true, }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), ], });

最後のステップは、依存関係をインストールしてファイルをコンパイルすることです。

 npm install npm run dev

そして出来上がり! Vue.js 3 と Vite で動作する Laravel 9 アプリケーションを手に入れました。 今、私たちは実際に何かが起こっているのを見る必要があります!

慣性ページの作成

ホームページと 1 つの記事を表示するための 2 つのブレード ファイル ( indexshow ) を覚えていますか?

Inertia を使用する際に必要なブレード ファイルはapp.blade.php だけです。これは、Inertia をインストールしたときに既に使用したものです。 では、これらのファイルはどうなるのでしょうか?

これらのファイルをブレード コンポーネントから Inertia.js コンポーネントに変換します。

アプリケーションの各ページには、慣性を備えた独自のコントローラーと JavaScript コンポーネントがあります。 これにより、API を使用せずに、そのページに必要なデータのみを取得できます。 慣性ページは JavaScript コンポーネントにすぎません。私たちの場合、それらは Vue.js コンポーネントです。 それらについて特に注目すべき点はありません。 したがって、すべての HTML コンテンツを<template>タグで囲み、JavaScript に関連するものはすべて<script>タグで囲みます。

「Pages」というフォルダを作成し、そこにファイルを移動します。 したがって、「 ./resources/js/Pages 」に「 index.blade.php 」と「 show.blade.php 」があります。 次に、ファイル形式を「.blade.php」ではなく「.vue」に変更し、名前の最初の文字を大文字にして、その内容を標準の Vue.js コンポーネントに変換します。 <html><head> 、および<body>タグは、メインのルート ブレード コンポーネントに既に含まれているため、除外します。

“resources/js/Pages/ Index.vue ”:

 <script setup> // </script> <template> <header> <h1>Kinsta Blog</h1> </header> <main> <h2>Read our latest articles</h2> <section> <article> <div> <img src="/images/kinsta-logo.png" alt="Article thumbnail" /> </div> <h3>Title for the blog</h3> <p> Lorem, ipsum dolor sit amet consectetur adipisicing elit. Illum rem itaque error vel perferendis aliquam numquam dignissimos, expedita perspiciatis consectetur! </p> <a href="#">Read more</a> </article> </section> </main> <footer> <h2>Join our Newsletter</h2> <input type="email" /> </footer> </template>

“resources/js/Pages/ Show.vue ”:

 <script setup> // </script> <template> <header> <h1>Welcome to Kinsta Blog</h1> </header> <main> <article> <h1>Title for the blog</h1> <p>Article content goes here</p> </article> </main> <footer> <h2>Join our Newsletter</h2> <input type="email" /> </footer> </template>

すごく気になるものがあります! 各コンポーネントのヘッダーとフッターをコピーして貼り付けますが、これはあまり良い方法ではありません。 永続コンポーネントを格納する慣性基本レイアウトを作成しましょう。

/resources/js 」に「Layouts」というフォルダーを作成し、そのフォルダー内に「KinstaLayout.vue」という名前のファイルを作成します。 このファイルには、ヘッダーとフッター、および<slot />を含むmainがあり、このレイアウトでラップされたすべてのコンポーネントをその中に埋め込むことができます。 このファイルは次のようになります。

“resources/js/Layouts/ KinstaLayout.vue ”:

 <script setup></script> <template> <header> <h1>Kinsta Blog</h1> </header> <main> <slot /> </main> <footer> <h2>Join our Newsletter</h2> <input type="email" /> </footer> </template>

次に、この新しいレイアウトをページにインポートし、すべての HTML コンテンツをラップします。 コンポーネントは次のようになります。

Index.vue :

 <script setup> import KinstaLayout from "../Layouts/KinstaLayout.vue"; </script> <template> <KinstaLayout> <section> <h2>Read our latest articles</h2> <article> <div> <img src="/images/kinsta-logo.png" alt="Article thumbnail" /> </div> <h3>Title for the blog</h3> <p> Lorem, ipsum dolor sit amet consectetur adipisicing elit. Illum rem itaque error vel perferendis aliquam numquam dignissimos, expedita perspiciatis consectetur! </p> <a href="#">Read more</a> </article> </section> </KinstaLayout> </template>

Show.vue :

 <script setup> import KinstaLayout from "../Layouts/KinstaLayout.vue"; </script> <template> <KinstaLayout> <article> <h1>Title for the blog</h1> <p>Article content goes here</p> </article> </KinstaLayout> </template>

Laravel ルートと慣性レンダー

まず、チュートリアルの開始点から取得した「 ArticleFactory 」ファイルを使用して、いくつかの記事をデータベースにシードします。

“データベース/シーダー/ databaseSeeder.php “:

 <?php namespace DatabaseSeeders; use AppModelsArticle; use IlluminateDatabaseSeeder; class DatabaseSeeder extends Seeder { public function run() { Article::factory(10)->create(); } }

次に、以下のターミナル コマンドを実行して、テーブルを移行し、ファクトリから偽のデータをシードします。

 php artisan migrate:fresh --seed

これにより、データベースに 10 個の偽の記事が作成され、Laravel ルーティングを使用してビューに渡す必要があります。 Inertia を使用してビューをレンダリングするようになったので、ルートを記述する方法が少し変わります。 最初の Laravel Inertia ルートを「routes/ web.php 」に作成し、「/resources/js/Pages/ Index.vue 」からホームページ ビューを返しましょう。

“ルート/ web.php “:

 <?php use AppModelsArticle; use IlluminateSupportFacadesRoute; use InertiaInertia; Route::get('/', function () { return Inertia::render('Index', [ 'articles' => Article::latest()->get() ]); })->name('home');

Inertiaをインポートし、ビューを返すためにview() Laravel ヘルパーを使用せず、代わりにInertia::renderを使用したことに注意してください。 Inertia はデフォルトで、「resources/js」のPagesフォルダー内のルートで言及したファイル名も探します。

インデックス ファイルに移動し、取得したデータを prop として設定し、それらをv-forでループして結果を表示します。 script タグの間に、渡されたデータを prop として定義します。 Inertia が知る必要があるのは、想定しているデータのタイプだけです。この場合、これは記事の配列を含む「Article」オブジェクトです。

“resources/js/Pages/ Index.vue ”:

 <script setup> import KinstaLayout from "../Layouts/KinstaLayout.vue"; defineProps({ Articles: Object, }); </script>

Vue.js 3 コンポジション API のsetup形式を使用しているため、それを返さずに prop として定義するだけで十分であることに注意してください。 オプション API を使用している場合は、それを返す必要があります。

ループを作りましょう:

 <template> <KinstaLayout> <h2>Read our latest articles</h2> <section> // Looping over articles <article v-for="article in articles":key="article.id"> <div> <img src="/images/kinsta-logo.png" alt="Article thumbnail" /> </div> <h3>{{article.title}}</h3> <p>{{article.excerpt}}</p> <a href="#">Read more</a> </article> </section> </KinstaLayout> </template>

npm run dev (Vite を使用しているため、実行したままにしておきます) とphp artisan serveを使用して、laravel 開発サーバーを起動し、Web サイトにアクセスすると、データベース内の 10 個の記事すべてを表示する期待されるページが表示されます。

現在、Google Chrome の Vue DevTools 拡張機能を使用しているため、アプリケーションをデバッグできます。 データがどのようにコンポーネントに渡されるかを見てみましょう。

開いているページの Inertia プロパティのリストを表示する Chrome の Vue DevTools 拡張機能。
慣性プロパティの検査。

「Articles」は、記事の配列を含む prop オブジェクトとしてコンポーネントに渡されます。 配列内の各記事は、データベースから取得したデータに対応するプロパティを持つオブジェクトでもあります。 これは、Laravel から Inertia に転送するすべてのデータが prop として扱われることを意味します。

Inertia.js で Tailwind CSS を使用する

Tailwind はプロジェクトの開始時点で既にインストールされているため、慣性コンポーネントを読み取るよう指示するだけです。 これは、次のように「 tailwind.config.js 」を編集することで実現できます。

 /** @type {import('tailwindcss').Config} */ module.exports = { content: [ "./storage/framework/views/*.php", "./resources/views/**/*.blade.php", "./resources/js/**/*.vue", ], theme: { extend: {}, }, plugins: [], };

次に、「resources/js/ app.js 」に CSS ファイルをインポートしたことを確認します。

 import "../css/app.css";

これで、コンポーネントのスタイルを設定する準備が整いました。

“resources/js/Pages/ Index.vue ”:

 <script setup> import KinstaLayout from "../Layouts/KinstaLayout.vue"; defineProps({ articles: Object, }); </script> <template> <KinstaLayout> <h2 class="text-2xl font-bold py-10">Read our latest articles</h2> <section class="space-y-5 border-b-2 pb-10"> <article v-for="article in articles" :key="article.id" class="flex justify-center items-center shadow-md bg-white rounded-xl p-4 mx-auto max-w-3xl" > <img src="/images/kinsta-logo.png" class="w-32 h-32 rounded-xl object-cover" alt="" /> <div class="flex flex-col text-left justify-between pl-3 space-y-5"> <h3 class="text-xl font-semibold text-indigo-600 hover:text-indigo-800" > <a href="#">{{ article.title }}</a> </h3> <p> {{ article.excerpt }} </p> <a href="#" class="text-indigo-600 hover:text-indigo-800 w-fit self-end font-semibold" >Read more</a > </div> </article> </section> </KinstaLayout> </template>

“resources/js/Layouts/ KinstaLayout.vue ”:

 <script setup></script> <template> <Header class="bg-gradient-to-r from-blue-700 via-indigo-700 to-blue-700 w-full text-center py-4" > <h1 class="text-white font-bold text-4xl">Kinsta Blog</h1> </Header> <main class="container mx-auto text-center"> <slot /> </main> <footer class="bg-gradient-to-b from-transparent to-gray-300 w-full text-center mt-5 py-10 mx-auto" > <h2 class="font-bold text-xl pb-5">Join our Newsletter</h2> <input class="rounded-xl w-80 h-12 px-3 py-2 shadow-md" type="email" placeholder="Write your email.." /> </footer> </template>

ブラウザーを見ると、Vite が既に Tailwind マジックでページを更新していることに気付くでしょう。

以前の「Kinsta Blog」の例の機能バージョンを示すスクロール画像。
慣性プロパティのレンダリング。

慣性リンク

データベース内のすべての記事を表示できる実用的なホームページができたので、個々の記事を表示する別のルートを作成する必要があります。 新しいルートを作成し、URL を「id」ワイルドカードに設定しましょう。

「ルート/web.php

 <?php use AppModelsArticle; use IlluminateSupportFacadesRoute; use InertiaInertia; Route::get('/', function () { return Inertia::render('Index', [ 'articles' => Article::latest()->get() ]); })->name('home'); Route::get('/posts/{article:id}', function (Article $article) { return Inertia::render('Show', [ 'article' => $article ]); })->name('article.show');

「Article」モデルをインポートし、 Show.vue Inertia コンポーネントを返す新しいルートを追加しました。 また、Laravel のルート モデル バインディングも活用しました。これにより、Laravel は参照している記事を自動的に取得できます。

ここで必要なのは、ページ全体をリロードせずに、ホームページからリンクをクリックしてこのルートにアクセスする方法だけです。 イナーシャの魔法道具<Link>で可能。 Inertia は<Link>を標準のアンカー タグ<a>のラッパーとして使用し、このラッパーはページ アクセスを可能な限りシームレスにすることを意図していることを紹介で述べました。 Inertia では、 <Link>タグは<GET>リクエストを実行するアンカー タグとして動作できますが、同時に<button><form>として動作することもできます。 それをプロジェクトに適用する方法を見てみましょう。

Index.vue で、Inertia から<Link>をインポートし、アンカー タグ<a>を削除して Inertia <Link>タグに置き換えます。 href属性は、記事を表示するために以前に作成したルート URL に設定されます。

 <script setup> import KinstaLayout from "../Layouts/KinstaLayout.vue"; import { Link } from "@inertiajs/inertia-vue3"; defineProps({ articles: Object, }); </script> <template> <KinstaLayout> <section class="space-y-5 border-b-2 pb-10"> <h2 class="text-2xl font-bold pt-10 mx-auto text-center"> Read our latest articles </h2> <article v-for="article in articles" :key="article.id" class="flex justify-center items-center shadow-md bg-white rounded-xl p-4 mx-auto max-w-3xl" > <img src="/images/kinsta-logo.png" class="w-32 h-32 rounded-xl object-cover" alt="" /> <div class="flex flex-col text-left justify-between pl-3 space-y-5" > <h3 class="text-xl font-semibold text-indigo-600 hover:text-indigo-800" > <Link :href="'/posts/' + article.id">{{ article.title }}</Link> </h3> <p> {{ article.excerpt }} </p> <Link :href="'/posts/' + article.id" class="text-indigo-600 hover:text-indigo-800 w-fit self-end font-semibold" >Read more </Link> </div> </article> </section> </KinstaLayout> </template>

Tailwind を使用してShow.vueのスタイルを設定し、もう少しドレスアップして訪問の準備を整えましょう。 また、「記事」オブジェクトを期待し、小道具として設定する必要があることを知らせる必要があります。

 <script setup> import KinstaLayout from "../Layouts/KinstaLayout.vue"; defineProps({ article: Object, }); </script> <template> <KinstaLayout> <article class="mx-auto mt-10 flex justify-center max-w-5xl border-b-2"> <img src="/images/kinsta-logo.png" class="w-80 h-80 rounded-xl mx-auto py-5" alt="" /> <div class="text-left flex flex-col pt-5 pb-10 px-10"> <h1 class="text-xl font-semibold mb-10">{{ article.title }}</h1> <p>{{ article.body }}</p> </div> </article> </KinstaLayout> </template>

記事のタイトルまたは「続きを読む」をクリックすると、魔法のようにページを更新せずにShow.vueに移動します。

ダウンタイムや WordPress の問題に悩まされていませんか? Kinstaは、時間を節約するために設計されたホスティングソリューションです! 私たちの機能をチェックしてください
有効なリンクを含む記事カードを表示する「Kinsta ブログ」ページの例。
慣性リンクが配置されています。

この場合、ルートにGETリクエストを送信して新しいデータを返すアンカー タグとして<Link>を使用していますが、 <Link>POSTPUTPATCH 、およびDELETEにも使用できます。

“ルート/ web.php “:

 <Link href="/logout" method="post" as="button" type="button">Logout</Link>

知っておくべき Laravel Inertia のヒントとコツ

これで、Laravel、Inertia、Tailwind CSS で構築された実用的な SPA ができました。 しかし慣性は、私たちがさらに多くのことを達成するのに役立ちます。 開発者とアプリケーション訪問者の両方に役立ついくつかの慣性テクニックを習得する時が来ました。

URL の生成

Laravel ルートを使用せずに名前を追加していることに気付いたかもしれません。 慣性により、完全なルートを手動で書き留める代わりに、コンポーネント内で名前付きルートを使用できます。

これは、プロジェクトに Ziggy パッケージをインストールすることで実現できます。

 composer require tightenco/ziggy

次に、「resources/js/app.js」に移動して、次のように更新します。

 import "./bootstrap"; import "../css/app.css"; import { createApp, h } from "vue"; import { createInertiaApp } from "@inertiajs/inertia-vue3"; import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers"; import { ZiggyVue } from "../../vendor/tightenco/ziggy/dist/vue.m"; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => resolvePageComponent( `./Pages/${name}.vue`, import.meta.glob("./Pages/**/*.vue") ), setup({ el, app, props, plugin }) { return createApp({ render: () => h(app, props) }) .use(plugin) .use(ZiggyVue, Ziggy) .mount(el); }, });

「/resources/views/ app.blade.php 」に移動し、 @routeディレクティブでヘッドを更新します。

 <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Fetch project name dynamically --> <title inertia>{{ config('app.name', 'Laravel') }}</title> <!-- Scripts --> @routes @vite('resources/js/app.js') @inertiaHead </head> <body class="font-sans antialiased"> @inertia </body> </html>

…そして、以下の 2 つのターミナル コマンドを実行して、NPM パッケージを更新します。

 npm install && npm run dev

このパッケージにより、Inertia コンポーネント内で名前付きルートを使用できるようになるため、 Index.vueに移動して、古い手動ルートを削除し、コントローラー内にいるかのように通常どおりデータを渡しながらルート名に置き換えましょう。

これを置き換えます:

 <Link :href="'/posts/' + article.id"> {{ article.title }} </Link>

…これとともに:

 <Link :href="route('article.show', article.id)"> {{ article.title }} </Link>

これにより、以前とまったく同じ動作が得られますが、より開発者にとって使いやすく、ルートが多くのパラメーターを必要とする場合に非常に役立ちます。

進行状況インジケーター

これは、Inertia.js の最も優れた機能の 1 つです。 SPA はインタラクティブなユーザー エクスペリエンスを提供するため、リクエストが読み込まれているかどうかを常にフィードバックすることは、アプリケーションへの素晴らしい追加となります。 これは、Inertia が提供する別のライブラリによって実現できます。

「@inertiajs/progress」ライブラリは、NProgress のラッパーであり、Inertia イベントに応じてロード インジケーターを条件付きで表示します。 これが舞台裏でどのように機能するかを実際に知る必要はないので、機能させてみましょう。

以下の端末コマンドでこのライブラリをインストールできます。

 npm install @inertiajs/progress

インストールしたら、「 resources/js/app.js 」にインポートする必要があります

import "./bootstrap"; import "../css/app.css"; import { createApp, h } from "vue"; import { createInertiaApp } from "@inertiajs/inertia-vue3"; import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers"; import { ZiggyVue } from "../../vendor/tightenco/ziggy/dist/vue.m"; import { InertiaProgress } from "@inertiajs/progress"; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => resolvePageComponent( `./Pages/${name}.vue`, import.meta.glob("./Pages/**/*.vue") ), setup({ el, app, props, plugin }) { return createApp({ render: () => h(app, props) }) .use(plugin) .use(ZiggyVue, Ziggy) .mount(el); }, }); InertiaProgress.init({ color: "#000000", showSpinner: true });

これにより、読み込みバーと読み込みスピナーが黒色で表示されますが、Inertia.js プログレス インジケーターのドキュメントにあるその他の便利なオプションと共に色を変更できます。

右上に回転インジケーターがある青色の「Kinsta Blog」ヘッダー。
慣性進行状況インジケーター (右上)。

スクロール管理

場合によっては、同じスクロール位置を維持しながら新しいページに移動したい場合があります。 ユーザーがコメントを残すことを許可する場合、おそらくこれが必要になるでしょう。 これにより、フォームが送信され、新しいコメントがデータベースからコンポーネントに読み込まれます。 ユーザーがスクロール位置を失うことなくこれを行う必要があります。 慣性がこれを処理します。

私たちの場合、これをIndex.vue<Link>タグに適用しましょう。 Inertia の<Link>で別のページにリダイレクトする際にスクロール位置を保持するには、 <Link>preserve-scroll属性を追加するだけです。

 <Link :href="route('article.show', article.id)" preserve-scroll> {{ article.title }} </Link>

SEOのヒント

SPA の誕生以来、人々は検索エンジン最適化 (SEO) に関心を持ってきました。 SPA アプローチを使用すると、すべてがクライアント側でレンダリングされるため、検索エンジンが Web アプリケーションをクロールするのが難しくなり、結果として Web サイトが検索結果の上部に表示されなくなることがよく知られています。 それにもかかわらず、Facebook や Github などの人気のあるプラットフォームが現在 SPA であり、SEO で良好なパフォーマンスを維持しているのはなぜでしょうか?

これはミッションではありません。もはや不可能です。 Inertia は、SPA を SEO フレンドリーにするためのソリューションをいくつか提供しています。

Laravel と Vite を使用した Inertia Vue SSR

検索エンジンは、コンテンツを識別するために、常に Web サイトの HTML を探しています。 ただし、URL に HTML が含まれていない場合、この作業はさらに難しくなります。 SPA を開発するとき、ページにあるのは JavaScript と JSON だけです。 Inertia は、アプリケーションに追加できるサーバー側レンダリング (SSR) 機能を導入しました。 これにより、アプリはサーバーでの最初のページ アクセスを事前にレンダリングし、レンダリングされた HTML をブラウザーに送信できます。 これにより、ユーザーはページが完全に読み込まれる前にページを表示して操作できます。また、検索エンジンがサイトをインデックスに登録するのにかかる時間を短縮するなど、他の利点もあります.

仕組みを要約すると、Inertia は Node.js サーバー上で実行されているかどうかを識別し、コンポーネント名、プロパティ、URL、およびアセット バージョンを HTML にレンダリングします。 これにより、ユーザーと検索エンジンに、ページが提供するほぼすべてのものを提供できます。

ただし、Laravel を扱っているため、Laravel は PHP フレームワークであり、Node.js サーバーでは実行されないため、これはほとんど意味がありません。 そのため、ページをレンダリングして HTML を返す Node.js サービスにリクエストを転送します。 これにより、デフォルトで Laravel Vue アプリケーションが SEO フレンドリーになります。

まず、Vue.js SSR npm パッケージをインストールする必要があります。

 npm install @vue/server-renderer

もう 1 つの便利な慣性「NPM」パッケージは、単純な「HTTP」サーバーを提供します。 インストールすることを強くお勧めします:

 npm install @inertiajs/server

次に、「resources/js/」にssr.jsという名前の新しいファイルを追加します。 This file will be very similar to the app.js file we created when installing Inertia, only it will execute in Node.js rather than the browser:

 import { createSSRApp, h } from "vue"; import { renderToString } from "@vue/server-renderer"; import { createInertiaApp } from "@inertiajs/inertia-vue3"; import createServer from "@inertiajs/server"; import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers"; import { ZiggyVue } from "../../vendor/tightenco/ziggy/dist/vue.m"; const appName = "Laravel"; createServer((page) => createInertiaApp({ page, render: renderToString, title: (title) => `${title} - ${appName}`, resolve: (name) => resolvePageComponent( `./Pages/${name}.vue`, import.meta.glob("./Pages/**/*.vue") ), setup({ app, props, plugin }) { return createSSRApp({ render: () => h(app, props) }) .use(plugin) .use(ZiggyVue, { ...page.props.ziggy, location: new URL(page.props.ziggy.location), }); }, }) );

Make sure not to include everything in the ssr.js file since it will not be visible to visitors; this file is only for search engines and browsers to show the data within your page, so include only what is important to your data or only what will make your data available.

“By default, Inertia's SSR server will operate on port 13714. However, you can change this by providing a second argument to the createServer method.” Inertia DOCss.

The Inertia.js DOCs aren't explaining how to integrate Inertia SSR with Vite, but we will go through this now. Head to vite.config.js and paste the below:

 import { defineConfig } from "vite"; import laravel from "laravel-vite-plugin"; import vue from "@vitejs/plugin-vue"; export default defineConfig({ plugins: [ laravel({ input: "resources/js/app.js", ssr: "resources/js/ssr.js", }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), ], });

Next, head to package.json and change the build script:

 "build": "vite build && vite build --ssr"

Now if we run npm run build , Vite will build our SSR bundle for production. For more information about this you may visit Inertia SSR DOCs and Vite SSR DOCs.

Title and Meta

Because JavaScript applications are rendered within the document's <body> , they cannot render markup to the document's <head> because it is outside of their scope. Inertia has a <Head> component that may be used to set the page <title> , <meta> tags, and other <head> components.

To add <head> element to your Page, we must import <head> from Inertia same as we did with <Link> component:

import { Head } from '@inertiajs/inertia-vue3' <Head> <title>Kinsta Blog</title> <meta name="description" content="Kinsta blog for developers"> </Head>

すべてのページにグローバル タイトルを追加することもできます。これにより、すべてのページのタイトルの横にアプリケーション名が追加されます。 これはすでにapp.jsファイルで行っています。

 createInertiaApp({ title: (title) => `${title} - ${appName}`, // });

つまり、アプリケーションのホームページにタイトル付きの<head title="Homepage">を追加すると、これは<title>Home - My App</title>のようにレンダリングされます。

アプリの監視

速度は、Web サイトの SEO パフォーマンスを最適化する上で最も重要な要素の 1 つです。 このため、ウェブサイトに WordPress を使用している場合、Kinsta APM はアプリケーションの動作を監視し、監視するのに役立ちます。 WordPressのパフォーマンスの問題を特定するのに役立ち、Kinstaがホストするすべてのサイトで無料で利用できます.

概要

Inertia.js は、利用可能な最も重要なテクノロジの 1 つです。 これを Laravel と組み合わせると、PHP と JavaScript で構築された最新のシングルページ アプリケーションが完成します。 Laravel の作成者である Taylor Otwell は Inertia に非常に興味を持っているため、Laravel は最も人気のあるスターター キットである Laravel Breeze と Jetstream を Inertia と SSR をサポートしてリリースしました。
このガイドで、Inertia.js の使用を開始する方法と、Laravel、Vue.js、Tailwind CSS で使用して最新のブログ Web アプリを作成する方法を確認してください。
あなたが Laravel ファンまたはプロの開発者であれば、間違いなく Inertia.js に目を奪われるでしょう。 このチュートリアルでは、非常に基本的で簡単なブログをわずか数分で作成しました。 慣性について学ぶことはまだたくさんありますが、これは多くの記事やチュートリアルの最初に過ぎないかもしれません。

Laravel について他に調べてほしいことはありますか? 以下のコメントセクションでお知らせください。