Come utilizzare Inertia.js nei tuoi progetti Laravel
Pubblicato: 2022-12-08Le applicazioni multipagina (MPA) stanno diventando meno popolari di giorno in giorno. Piattaforme famose come Facebook, Twitter, YouTube, Github e molte altre stanno già utilizzando la tecnologia delle applicazioni a pagina singola (SPA).
Questa tecnologia alla moda consente agli utenti di interagire con le applicazioni Web in modo rapido e reattivo perché tutto viene visualizzato sul lato client. Tuttavia, può essere un problema per gli sviluppatori che creano applicazioni con rendering lato server con framework come Laravel o Django.
Fortunatamente, Inertia.js è intervenuto ed è venuto in soccorso.
In questo articolo, mostreremo come iniziare a utilizzare Inertia.js e come utilizzarlo con Laravel, Vue.js e Tailwind CSS per creare una moderna app web per blog. Condivideremo anche come rendere le SPA più SEO-friendly, oltre ad alcuni altri trucchi.
Se hai appena iniziato con Laravel, ti consigliamo di leggere prima questo articolo in modo da essere pronto a partire.
Perché SPA?
Prima di poter chiedere perché dovremmo usare Inertia, dobbiamo prima chiederci: "Perché SPA?"
Perché qualcuno dovrebbe preferire le applicazioni renderizzate lato client rispetto alle tradizionali applicazioni lato server? Cosa costringerebbe uno sviluppatore Laravel full-stack a dire addio ai componenti blade?
La risposta breve: perché la velocità e la reattività sono essenziali per qualsiasi coinvolgimento degli utenti di successo.
Nel caso degli MPA, il browser invia costantemente richieste al back-end, che esegue quindi numerose query del database. Dopo che il database e il server hanno elaborato le query e le hanno consegnate al browser, viene eseguito il rendering della pagina.
Ma le SPA sono diverse. L'applicazione porta tutto ciò che l'utente richiede direttamente alla pagina, eliminando la necessità per il browser di inviare query o ricaricare la pagina per visualizzare nuovi elementi HTML.
A causa di questa esperienza utente unica nel suo genere, molte aziende di grandi nomi chiedono a gran voce che i loro siti Web diventino applicazioni a pagina singola.
Detto questo, la creazione di un'applicazione a pagina singola può essere difficile per gli sviluppatori Laravel perché richiederebbe loro di iniziare a utilizzare Vue.js o React invece dei modelli blade, con la conseguente perdita di molte gemme Laravel che consentono di risparmiare tempo e fatica.
Ora che abbiamo Inertia.js, però, tutto è cambiato.
Perché inerzia?
Se gli sviluppatori di Laravel dovessero creare SPA Web con Vue prima di Inertia, dovrebbero configurare le API e restituire i dati JSON con Laravel, quindi utilizzare qualcosa come AXIOS per recuperare i dati nei componenti Vue. Richiederebbero anche qualcosa come Vue Router per gestire i percorsi, il che significherebbe perdere il routing Laravel, nonché middleware e controller.
Inertia.js, d'altra parte, consente agli sviluppatori di creare moderne app Vue, React e Svelte a pagina singola utilizzando il routing e i controller classici lato server. Inertia è stato progettato per gli sviluppatori di Laravel, Ruby on Rails e Django per consentire loro di creare app senza modificare le loro tecniche di codifica per la creazione di controller, il recupero di dati da un database e il rendering delle viste
Grazie a Inertia.js, gli sviluppatori di Laravel si sentiranno come a casa.
Come funziona l'inerzia
Costruire SPA solo con Laravel e Vue ti darà una pagina JavaScript completa per il tuo frontend, ma questo non ti fornirà un'esperienza di app a pagina singola. Ogni collegamento cliccato causerà il riavvio del framework lato client al successivo caricamento della pagina.
È qui che entra in gioco l'inerzia.
Inertia è fondamentalmente una libreria di routing lato client. Ti consente di navigare tra le pagine senza dover ricaricare l'intera pagina. Ciò si ottiene tramite il componente <Link>
, che è un involucro leggero attorno a un tag di ancoraggio standard.
Quando fai clic su un collegamento Inertia, Inertia intercetta il clic e ti reindirizza invece a XHR. Il browser non ricaricherà la pagina in questo modo, offrendo all'utente un'esperienza completa a pagina singola.
Iniziare con l'inerzia
Per comprendere Inertia e come integrarla con Laravel, creeremo un'app web per blog chiamata Kinsta Blog utilizzando la combinazione più potente, Laravel per il backend, Vue.js per il frontend JavaScript e Tailwind CSS per lo styling.
Se preferisci seguire questo tutorial in un ambiente locale, puoi utilizzare DevKinsta, un potente strumento per sviluppatori, designer e agenzie che consente loro di creare app Web WordPress singole e multipagina. Fortunatamente, WordPress può essere facilmente integrato con Laravel utilizzando il pacchetto Corcel.
Prerequisiti
Per ottenere il massimo da questo tutorial, dovresti avere familiarità con quanto segue:
- Nozioni di base su Laravel (installazione, database, migrazioni di database, modelli Eloquent, controller e routing)
- Nozioni di base su Vue.js (installazione, struttura e moduli)
Se non ti senti sicuro, dai un'occhiata a questi fantastici tutorial gratuiti e a pagamento di Laravel. Altrimenti, entriamo.
Fase uno: installa gli elementi principali
Per concentrarti su Inertia.js e arrivare subito alla parte divertente, assicurati di avere la seguente configurazione pronta per l'uso:
- Progetto Laravel 9 appena installato chiamato
kinsta-blog
- Tailwind CSS CLI installato nel nostro progetto Laravel
- Due componenti blade in kinsta-blog/resources/views per visualizzare la home page del blog e un singolo articolo sul blog come mostrato di seguito:
“/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>
- Database locale MySQL denominato
kinsta_blog
connesso al nostro progetto:" .env ":
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=kinsta_blog DB_USERNAME=root DB_PASSWORD=
- Modello articolo, migrazioni e factory:
“app/Modelli/ Articolo.php ”:
<?php namespace AppModels; use IlluminateDatabaseEloquentFactoriesHasFactory; use IlluminateDatabaseEloquentModel; class Article extends Model { use HasFactory; protected $fillable = ['title', 'excerpt', 'body']; }
“database/migrazioni/ 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'); } };
“database/fabbriche/ 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), ]; } }
Questo è tutto ciò di cui abbiamo bisogno per iniziare! Ora mettiamoci al lavoro e presentiamo Inertia.js al nostro progetto.
Passaggio 2: installare Inertia
Il processo di installazione di Inertia è suddiviso in due fasi principali: lato server (Laravel) e lato client (VueJs).
La guida all'installazione ufficiale nella documentazione di Inertia è un po' obsoleta perché Laravel 9 ora utilizza Vite per impostazione predefinita, ma esamineremo anche quella.
1. Lato server
La prima cosa che dobbiamo fare è installare gli adattatori lato server Inertia con il seguente comando terminale tramite Composer.
composer require inertiajs/inertia-laravel
Ora imposteremo il nostro modello di root, che sarà un singolo file blade che verrà utilizzato per caricare i file CSS e JS, nonché una radice di inerzia che verrà utilizzata per avviare la nostra applicazione JavaScript.
Poiché stiamo utilizzando la versione più recente di Laravel 9 v9.3.1, dobbiamo anche consentire a Vite di fare la sua magia includendolo nei nostri tag in /resources/views/ app.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" /> <!-- 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>
Nota come siamo in grado di recuperare dinamicamente il titolo del progetto aggiungendo l'attributo Inertia
ai tag <title>
.
Abbiamo anche aggiunto la direttiva @vite
in testa per far conoscere a Vite il percorso del nostro file principale JavaScript in cui abbiamo creato la nostra app e importato il nostro CSS. Vite è uno strumento che aiuta con lo sviluppo JavaScript e CSS consentendo agli sviluppatori di visualizzare le modifiche al frontend senza dover aggiornare la pagina durante lo sviluppo locale.
La nostra prossima mossa sarà creare il middleware HandleInertiaRequests e pubblicarlo nel nostro progetto. Possiamo farlo attivando il seguente comando terminale all'interno della directory principale del nostro progetto:
php artisan inertia:middleware
Una volta completato, vai su "App/Http/ Kernel " e registra HandleInertiaRequests
come ultimo elemento nei tuoi middleware web:
'web' => [ // ... AppHttpMiddlewareHandleInertiaRequests::class, ],
2. Lato client
Successivamente, dobbiamo installare le nostre dipendenze frontend Vue.js 3 nello stesso modo del lato server:
npm install @inertiajs/inertia @inertiajs/inertia-vue3 // or yarn add @inertiajs/inertia @inertiajs/inertia-vue3
Successivamente, devi inserire Vue.js 3:
npm install [email protected]
Quindi aggiorna il tuo file JavaScript principale per inizializzare Inertia.js con Vue.js 3, Vite e Laravel:
“risorse/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); }, });
Nello snippet di codice sopra, usiamo il plugin di resolvePageComponent
e gli diciamo di risolvere i nostri componenti dalla directory ./Pages/$name.vue . Questo perché salveremo i nostri componenti Inertia in questa directory più avanti nel nostro progetto e questo plugin ci aiuterà a caricare automaticamente quei componenti dalla directory corretta.
Non resta che installare vitejs/plugin-vue
:
npm i @vitejs/plugin-vue
E aggiorna il file 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, }, }, }), ], });
Il passaggio finale è installare le nostre dipendenze e compilare i nostri file:
npm install npm run dev
E voilà! Hai un'applicazione Laravel 9 funzionante con Vue.js 3 e Vite. Ora dobbiamo vedere qualcosa che accade in azione!
Creazione di pagine di inerzia
Ricordi quei due file blade ( index e show ) per visualizzare la nostra homepage e un singolo articolo?
L'unico file blade di cui avremo bisogno durante l'utilizzo di Inertia è app.blade.php , che abbiamo già utilizzato una volta durante l'installazione di Inertia. Quindi cosa succede a quei file ora?
Trasformeremo quei file da componenti blade in componenti Inertia.js.
Ogni pagina nella tua applicazione ha il proprio controller e componente JavaScript con Inertia. Ciò ti consente di ottenere solo i dati richiesti per quella pagina, senza utilizzare un'API. Le pagine Inertia non sono altro che componenti JavaScript, nel nostro caso sono componenti Vue.js. Non hanno nulla di particolarmente degno di nota in loro. Quindi quello che faremo è avvolgere tutto il contenuto HTML tra i tag <template>
e tutto ciò che riguarda JavaScript sarà racchiuso tra i tag <script>
.
Crea una cartella chiamata "Pagine" e sposta i tuoi file lì. Quindi avremo " index.blade.php " e " show.blade.php " in " ./resources/js/Pages ". Quindi modificheremo il formato del file in ".vue" invece di ".blade.php" rendendo maiuscola la prima lettera dei loro nomi e trasformeremo il suo contenuto in un componente Vue.js standard. Escluderemo i <html>
, <head>
e <body>
perché sono già inclusi nel componente root blade principale.
“risorse/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>
“risorse/js/Pagine/ 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>
C'è qualcosa che mi preoccupa davvero! Continuiamo a copiare e incollare la nostra intestazione e piè di pagina in ogni componente, il che non è una buona pratica. Creiamo un layout di base Inertia per memorizzare i nostri componenti persistenti.
Crea una cartella chiamata "Layouts" in " /resources/js " e all'interno di quella cartella crea un file chiamato "KinstaLayout.vue". Questo file avrà la nostra intestazione e piè di pagina e il main
con uno <slot />
per consentire a tutti i componenti racchiusi in questo layout di essere incorporati al suo interno. Questo file dovrebbe assomigliare a questo:
“risorse/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>
Quindi importeremo questo nuovo layout nelle nostre pagine e avvolgeremo tutto il contenuto HTML con esso. I nostri componenti dovrebbero assomigliare a questo:
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>
Mostra.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 Routes e Inertia Render
Per prima cosa usiamo il file " ArticleFactory " che abbiamo dal punto di partenza del nostro tutorial e seminiamo alcuni articoli nel nostro database.
“database/seeder/ databaseSeeder.php “:
<?php namespace DatabaseSeeders; use AppModelsArticle; use IlluminateDatabaseSeeder; class DatabaseSeeder extends Seeder { public function run() { Article::factory(10)->create(); } }
Quindi premi il comando del terminale di seguito per migrare le tue tabelle e seminare i dati falsi dalle fabbriche:
php artisan migrate:fresh --seed
Questo creerà 10 articoli falsi nel database, che dovremo passare alla nostra vista usando il routing Laravel. Ora che stiamo usando Inertia per il rendering delle viste, il modo in cui scrivevamo i nostri percorsi cambierà leggermente. Creiamo il nostro primo percorso Laravel Inertia in "routes/ web.php " e restituiamo la visualizzazione della home page da "/resources/js/Pages/ Index.vue ".
“percorsi/ web.php “:
<?php use AppModelsArticle; use IlluminateSupportFacadesRoute; use InertiaInertia; Route::get('/', function () { return Inertia::render('Index', [ 'articles' => Article::latest()->get() ]); })->name('home');
Si noti che abbiamo importato Inertia
e non abbiamo usato l'helper Laravel view()
per restituire la vista, ma invece abbiamo usato Inertia::render
. Inertia cercherà anche per impostazione predefinita il nome del file che abbiamo menzionato nel nostro percorso nella cartella Pages in "resources/js".
Vai al file indice e imposta i dati recuperati come prop e passaci sopra con v-for
per mostrare i risultati. Tra i tag di script, definisci i dati passati come prop. Tutto ciò che Inertia deve sapere è quale tipo di dati ti aspetti, che nel nostro caso è un oggetto "Articolo" contenente un array di articoli.
“risorse/js/Pages/ Index.vue “:
<script setup> import KinstaLayout from "../Layouts/KinstaLayout.vue"; defineProps({ Articles: Object, }); </script>
Nota che è sufficiente definirlo solo come prop senza restituirlo perché stiamo usando il formato di setup
per l'API di composizione Vue.js 3. Se utilizziamo l'API delle opzioni, dovremmo restituirlo.
Facciamo il giro:
<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
(lasciarlo in esecuzione perché stiamo usando Vite) e php artisan serve
per avviare il server di sviluppo laravel e accedere al nostro sito Web, vedremo la pagina prevista che mostra tutti e dieci gli articoli nel database.
Ora stiamo utilizzando l'estensione Vue DevTools di Google Chrome, che ci consente di eseguire il debug della mia applicazione. Ti mostriamo come i nostri dati vengono passati al componente.
"Articoli" viene passato al componente come oggetto prop contenente un array di articoli; ogni articolo nell'array è anche un oggetto con proprietà che corrispondono ai dati acquisiti dal database. Ciò significa che tutti i dati che trasferiamo da Laravel a Inertia saranno trattati come prop.
Utilizzo di Tailwind CSS con Inertia.js
Poiché Tailwind è già installato nel nostro progetto al punto di partenza, tutto ciò che dobbiamo fare è dirgli di leggere i nostri componenti Inertia. Ciò può essere ottenuto modificando " tailwind.config.js " come segue:
/** @type {import('tailwindcss').Config} */ module.exports = { content: [ "./storage/framework/views/*.php", "./resources/views/**/*.blade.php", "./resources/js/**/*.vue", ], theme: { extend: {}, }, plugins: [], };
Quindi assicurati di aver importato il nostro file CSS in "resources/js/ app.js ":
import "../css/app.css";
E ora siamo pronti per modellare i nostri componenti.
“risorse/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>
“risorse/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>
Se guardi il browser, noterai che Vite ha già aggiornato la pagina con la magia di Tailwind.
Collegamenti di inerzia
Ora che disponiamo di una home page funzionante in grado di visualizzare tutti gli articoli nel database, dobbiamo creare un altro percorso per visualizzare i singoli articoli. Creiamo un nuovo percorso e impostiamo l'URL su un carattere jolly "id":
“percorsi/ 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');
Abbiamo importato il modello "Article" e aggiunto un nuovo percorso per restituire il componente Show.vue Inertia. Abbiamo anche sfruttato l'associazione del modello di percorso di Laravel, che consente a Laravel di ottenere automaticamente l'articolo a cui ci riferiamo.
Tutto ciò di cui abbiamo bisogno ora è un modo per visitare questo percorso facendo clic su un collegamento dalla home page senza dover ricaricare l'intera pagina. Questo è possibile con lo strumento magico di Inertia <Link>
. Abbiamo menzionato nell'introduzione che Inertia utilizza <Link>
come wrapper per un tag di ancoraggio standard <a>
e che questo wrapper ha lo scopo di rendere le visite alle pagine il più fluide possibile. In Inertia, il tag <Link>
può comportarsi come un tag di ancoraggio che esegue richieste <GET>
, ma può anche fungere da <button>
e da <form>
allo stesso tempo. Vediamo come possiamo applicarlo al nostro progetto.
Nel nostro Index.vue, importeremo <Link>
da Inertia, rimuoveremo i tag di ancoraggio <a>
e li sostituiremo con i tag Inertia <Link>
. L'attributo href
verrà impostato sull'URL del percorso che abbiamo creato in precedenza per visualizzare l'articolo:
<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>
Diamo uno stile a Show.vue con Tailwind per farlo sembrare un po' più elegante e pronto per la nostra visita. E dobbiamo anche fargli sapere che dovrebbe aspettarsi un oggetto "Articolo" e impostarlo come oggetto di scena:
<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>
Ora, quando clicchiamo sul titolo dell'articolo o su "Leggi di più", verremo magicamente trasportati su Show.vue senza aggiornare la pagina.
Nel nostro caso, stiamo usando <Link>
come anchor tag che invia una richiesta GET
al percorso e restituisce i nuovi dati, ma possiamo usare <Link>
anche per POST
, PUT
, PATCH
e DELETE
“percorsi/ web.php “:
<Link href="/logout" method="post" as="button" type="button">Logout</Link>
Suggerimenti e trucchi per l'inerzia di Laravel che dovresti sapere
Ora abbiamo una SPA funzionante costruita con Laravel, Inertia e Tailwind CSS. Ma l'inerzia può aiutarci a ottenere molto di più. È tempo di acquisire alcune tecniche di inerzia che aiuteranno sia gli sviluppatori che i visitatori dell'applicazione.
Generazione di URL
Potresti aver notato che abbiamo aggiunto nomi ai nostri percorsi Laravel senza usarlo. L'inerzia ci consente di utilizzare i nostri percorsi denominati all'interno dei nostri componenti invece di scrivere manualmente l'intero percorso.
Possiamo raggiungere questo obiettivo installando il pacchetto Ziggy nel nostro progetto:
composer require tightenco/ziggy
Quindi vai su "resources/js/app.js" e aggiornalo in questo modo:
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); }, });
Vai a "/resources/views/ app.blade.php " e aggiorna l'intestazione con la direttiva @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>
... e aggiorna i tuoi pacchetti NPM premendo i due comandi del terminale seguenti:
npm install && npm run dev
Questo pacchetto ci consente di utilizzare percorsi denominati all'interno dei nostri componenti Inertia, quindi andiamo su Index.vue e rimuoviamo il vecchio percorso manuale e sostituiamolo con il nome del percorso passando i dati normalmente come se fossimo nel nostro controller.
Sostituiremo questo:
<Link :href="'/posts/' + article.id"> {{ article.title }} </Link>
…con questo:
<Link :href="route('article.show', article.id)"> {{ article.title }} </Link>
Questo ci darà esattamente lo stesso comportamento che abbiamo avuto, ma è più intuitivo per gli sviluppatori ed estremamente utile quando il tuo percorso prevede molti parametri.
Indicatori di progresso
Questa è una delle caratteristiche più interessanti di Inertia.js; poiché SPA offre un'esperienza utente interattiva, avere un feedback costante sul caricamento di una richiesta sarebbe un'aggiunta fantastica all'applicazione. Ciò può essere ottenuto da una libreria separata offerta da Inertia.
La libreria "@inertiajs/progress" è un wrapper attorno a NProgress che mostra in modo condizionale gli indicatori di caricamento in base agli eventi Inertia. Non hai davvero bisogno di sapere come funziona dietro le quinte, quindi facciamolo funzionare.
Possiamo installare questa libreria con il seguente comando terminale:
npm install @inertiajs/progress
Una volta installato, dobbiamo importarlo in " 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 });
Questo mostrerà una barra di caricamento e uno spinner di caricamento in colore nero, ma possiamo cambiare il colore insieme ad altre utili opzioni che possono essere trovate nella documentazione dell'indicatore di avanzamento di Inertia.js.
Gestione scorrimento
In alcuni casi, potresti voler passare a una nuova pagina mantenendo la stessa posizione di scorrimento. Forse ne avrai bisogno se consenti agli utenti di lasciare commenti; questo invierà un modulo e caricherà il nuovo commento dal database nel tuo componente; vorrai che ciò accada senza che l'utente perda la posizione di scorrimento. L'inerzia si prende cura di questo per noi.
Nel nostro caso, applichiamolo al nostro tag <Link>
in Index.vue . Per preservare la posizione di scorrimento durante il reindirizzamento a una pagina diversa con <Link>
di Inertia, tutto ciò che dobbiamo fare è aggiungere l'attributo preserve-scroll
a <Link>
:
<Link :href="route('article.show', article.id)" preserve-scroll> {{ article.title }} </Link>
Suggerimenti SEO
Sin dalla nascita delle SPA, le persone si sono preoccupate dell'ottimizzazione per i motori di ricerca (SEO). È risaputo che se si utilizza l'approccio SPA, i motori di ricerca avranno difficoltà a eseguire la scansione dell'applicazione Web perché tutto viene visualizzato sul lato client, con il risultato che il sito Web non viene visualizzato nella parte superiore dei risultati di ricerca; tuttavia, come mai quelle piattaforme popolari come Facebook e Github ora sono SPA e continuano a funzionare bene in SEO?
Bene, questa non è una missione: impossibile più. Inertia offre alcune soluzioni per aiutare la tua SPA a diventare SEO friendly.
Inertia Vue SSR Con Laravel e Vite
I motori di ricerca sono sempre alla ricerca di HTML sul tuo sito Web per identificare il contenuto; tuttavia, se non hai HTML nei tuoi URL, questo lavoro diventa più difficile. Quando sviluppi SPA, tutto ciò che hai sulla tua pagina è JavaScript e JSON. Inertia ha introdotto una funzionalità di rendering lato server (SSR) che puoi aggiungere alla tua applicazione. Ciò consente alla tua app di eseguire il pre-rendering di una visita alla pagina iniziale sul server e quindi di inviare l'HTML di cui è stato eseguito il rendering al browser. Ciò consente agli utenti di vedere e interagire con le tue pagine prima che si carichino completamente e presenta anche altri vantaggi, come la riduzione del tempo necessario ai motori di ricerca per indicizzare il tuo sito.
Per riassumere come funziona, Inertia identificherà se è in esecuzione su un server Node.js e renderà i nomi dei componenti, le proprietà, l'URL e la versione delle risorse in HTML. Ciò fornirà all'utente e al motore di ricerca praticamente tutto ciò che la tua pagina ha da offrire.
Tuttavia, poiché abbiamo a che fare con Laravel, questo ha poco senso perché Laravel è un framework PHP e non funziona su un server Node.js. Pertanto, inoltreremo la richiesta a un servizio Node.js, che eseguirà il rendering della pagina e restituirà HTML. Ciò renderà la nostra applicazione Laravel Vue SEO friendly per impostazione predefinita.
First, we need to install the Vue.js SSR npm package:
npm install @vue/server-renderer
Another helpful Inertia “NPM” package provides a simple “HTTP” server. It is strongly recommended that you install it:
npm install @inertiajs/server
Then, in “resources/js/”, we'll add a new file named 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>
Possiamo anche aggiungere un titolo globale per tutte le pagine, questo aggiungerà il nome della tua applicazione accanto al titolo in ogni pagina. Lo abbiamo già fatto nel file app.js :
createInertiaApp({ title: (title) => `${title} - ${appName}`, // });
Il che significa che se aggiungiamo <head title="Homepage">
nella home page della nostra applicazione con un titolo, questo verrà visualizzato in questo modo: <title>Home - My App</title>
.
Monitoraggio della tua app
La velocità è uno dei fattori più importanti per ottimizzare le prestazioni SEO sul tuo sito web. Se utilizzate WordPress per il vostro sito web, per questo motivo Kinsta APM vi assisterà nel monitoraggio e nel tenere d'occhio la vostra applicazione in azione. Ti aiuta a identificare i problemi di prestazioni di WordPress ed è disponibile gratuitamente su tutti i siti ospitati da Kinsta.
Riepilogo
Inertia.js è una delle tecnologie più significative disponibili; mescolalo con Laravel e avrai una moderna applicazione a pagina singola costruita con PHP e JavaScript. Taylor Otwell, il creatore di Laravel, è così interessato a Inertia che Laravel ha lanciato i suoi starter kit più popolari, Laravel Breeze e Jetstream, con il supporto di Inertia e SSR.
Se sei un fan di Laravel o uno sviluppatore professionista, Inertia.js attirerà senza dubbio la tua attenzione. In questo tutorial, abbiamo creato un blog molto semplice e diretto in pochi minuti. C'è ancora molto da imparare sull'inerzia, e questo potrebbe essere solo il primo di molti articoli e tutorial.
Cos'altro di Laravel vorresti che esplorassimo? Fateci sapere nella sezione commenti qui sotto.