Single-page applicaties (SPA’s) zijn de moderne manier geworden om webapplicaties te maken, en Inertia.js is een toonaangevende tool waarmee developers SPA’s kunnen maken met zowel rendering aan de client- als aan de serverzijde.

In dit artikel bekijken we hoe Inertia het bouwen van SPA’s enorm vereenvoudigt en hoe het vele andere problemen voor developers oplost. We behandelen ook de belangrijkste features van de tool.

Maar voordat we beginnen, laten we er eerst voor zorgen dat we begrijpen hoe server-side en client-side applicaties werken.

Wat is server-side rendering?

Server-side rendering (SSR) is wanneer een applicatie de content van een webpagina kan renderen of weergeven op de server in plaats van in de browser. Wanneer een gebruiker probeert voorbeeld.com te bezoeken, doet de browser een verzoek aan de server om alle noodzakelijke informatie om deze specifieke webpagina weer te geven, en de server antwoordt onmiddellijk door de browser een volledig gerenderde pagina te geven.

Zoekmachines grijpen in en indexeren de door de server geleverde informatie voordat die de browser bereikt; dit staat bekend als zoekmachine-optimalisatie (search engine optimization/SEO). De browser zorgt dan voor de JavaScript content en resolvet deze, en de webpagina wordt aan de gebruiker getoond.

Een diagram met de stadia van serverzijde rendering.
Weergave van aan de serverzijde gerenderde content.

Het probleem met de SSR aanpak is dat het lang duurt om een volledig gerenderde pagina van de server te laden, wat geen prettige gebruikerservaring biedt. Daarom overwegen developers vaak SPA’s en client-side rendering.

Wat is client-side rendering?

Client-side rendering zorgt ervoor dat de browser alles wat hij nodig heeft om de webpagina te renderen van de clientzijde krijgt in plaats van een volledig gerenderde pagina te krijgen van de server. Als de pagina geladen is, stuurt de browser geen andere verzoeken naar de server, waardoor de surfervaring extreem snel is.

Een diagram met de stadia van clientzijde rendering.
Weergave van aan de clientzijde gerenderde content.

Client-side rendering hielp bij het ontstaan van SPA’s, waardoor het web een revolutie onderging. Je kunt een website maken waarbij de pagina niet opnieuw geladen hoeft te worden, ongeacht hoeveel links je aanklikt. Het maakt het voor de gebruiker eenvoudig om door de website te navigeren.

Hoewel SPA’s fantastisch zijn, heeft deze aanpak veel complexiteit en problemen die we vandaag zullen behandelen. Inertia pakt de meeste van deze problemen aan door effectief gebruik te maken van server-side frameworks. Het combineert de beste features van zowel server-side als client-side apps.

Wat is Inertia.js?

Inertia is geen JavaScript framework. In plaats daarvan is het een strategie of techniek voor het ontwikkelen van SPA’s. Het stelt de developer in staat de huidige server-side frameworks te gebruiken om een moderne SPA te bouwen zonder de complexiteit die daarmee gepaard gaat.

Inertia is ontworpen om de frameworks die je al gebruikt te begeleiden, niet te vervangen. Beschouw het als een behulpzame bondgenoot die je helpt taken sneller en efficiënter uit te voeren. Het ondersteunt momenteel drie frontend frameworks (Vue, React en Svelte) voor rendering aan de clientzijde en twee backend frameworks (Laravel en Rails) voor rendering aan de serverzijde.

Voor de meeste Laravel devlopers is Inertia een van de meest betrouwbare technieken voor het bouwen van SPA’s, omdat het hen in staat stelt om zowel frontend als backend frameworks met elkaar te verbinden.

Hoe werkt Inertia.js?

Inertia is vergelijkbaar met Vue Router, in die zin dat je ermee tussen pagina’s kunt bewegen zonder de hele pagina opnieuw te hoeven laden. Inertia werkt echter synchroon met je server-side framework. Dit is mogelijk dankzij Link, een wrapper voor de standaard anchortag. Wanneer op een Link wordt geklikt, onderschept Inertia het klikevent en stuurt een XHR verzoek naar de server, waardoor de server herkent dat het om een Inertia verzoek gaat en een JSON respons terugstuurt. Die respons bevat de JavaScript componentnaam en gegevens, waarna Inertia op magische wijze onnodige componenten verwijdert en vervangt door de componenten die nodig zijn voor het bezoeken van de nieuwe pagina en de geschiedenisstatus bijwerkt.

Een diepgaande blik in de functionaliteit van Inertia.js

Wanneer een bezoeker voorbeeld.com bezoekt, doet de browser een standaard verzoek voor een volledige pagina, en de server stuurt een compleet HTML respons terug alsof Inertia niet bestaat. Dit HTML respons heeft alle onderdelen van de site (CSS, JavaScript), maar bevat ook een extra onderdeel voor Inertia, namelijk de root div met het data-page attribuut dat JSON gegevens bevat voor de eerste pagina. Inertia gebruikt dan deze JSON gegevens om het frontend framework op te starten en de initiële pagina weer te geven.

Diagram met acties bij het eerste bezoek aan een webpagina bij gebruik van Inertia.js.
Inertia.js: initiële paginabezoekrespons.

Zodra de app is opgestart, zal elke route die de gebruiker volgt binnen hetzelfde domein met behulp van Link een XHR verzoek zijn met de X-Inertia header. Dit vertelt de server dat het een Inertia verzoek is.

De feedback komt als een JSON respons met de paginacontent, in plaats van een compleet HTML respons zoals bij het eerste bezoek.

Diagram met acties bij toegang tot andere routes bij gebruik van Inertia.js.
Inertia.js: Vervolgrespons op routebezoek.

Welke problemen lost Inertia.js op?

Inertia pakt een groot aantal problemen aan voor webontwikkelaars. Het doel van het maken van Inertia was om snelle en effectieve oplossingen te bieden voor alle complexiteit die komt kijken bij het ontwerpen van een SPA.

SPA complexiteit

Als developers een SPA zouden bouwen zonder Inertia, dan zouden ze REST of GraphQL API’s moeten maken en die beschermen met een of andere authenticatiemethode, waardoor ze onder andere een frontend state-managementsysteem zouden moeten maken.

Inertia is ontworpen om developers te helpen hun server-side applicaties die volledig op de backendserver draaien om te zetten in een single-page JavaScript applicatie, zonder alle complexiteiten te hoeven doorlopen die komen kijken bij het bouwen van SPA’s.

Het maken van een SPA met Inertia is vergelijkbaar met het maken van een server-side gerenderde app. Je maakt controllers, doet queries naar de database voor de benodigde gegevens, en stuurt de resultaten terug naar de views.

Het belangrijkste hier is dat de views JavaScript componenten zijn. Dit betekent dat je de gegevens van je server haalt, waarna Inertia samenwerkt met het frontend framework om de pagina met de gegevens te tonen als een JavaScript bestand, zodat je geen API’s hoeft te maken.

Authenticatie

Omdat Inertia de applicatie voedt met gegevens en responsen van de backend, gebruikt het gewoon het authenticatiesysteem dat je op de server hebt. Dit betekent dat je je geen zorgen hoeft te maken over authenticatie aan de client-side – in plaats daarvan heb je een sessie-gebaseerd authenticatiesysteem dat synchroniseert met je authenticatiesysteem aan de kant van de server.

Zorgen rond SEO

Zoals eerder uitgelegd: bij server-side rendering onderscheppen zoekmachines de respons van de server aan de browser om de HTML content van de webpagina te indexeren. In het geval van een SPA zullen zoekmachines moeite hebben om de content van de pagina te identificeren, omdat de server zal reageren met JavaScript componenten en JSON gegevens.

Maar Inertia heeft dit probleem opgelost door de introductie van de server-side rendering (SSR) feature die je aan je applicatie kunt toevoegen. Inertia gebruikt de Node.js omgeving als een trigger om het JSON gegevensrespons om te zetten in HTML.

Om dit beter te illustreren: stel je voor dat Inertia tussen de server en de browser zit. Wanneer de server een Inertia verzoek ontvangt en een JSON respons terugstuurt, detecteert Inertia het bestaan van een Node.js server, zet het JSON respons om in HTML, en stuurt het terug, zodat zoekmachines de pagina kunnen indexeren alsof de app geen SPA is.

Inertia biedt ook een Head component, waarmee je een titel en metagegevens aan je pagina kunt toevoegen:


<script setup>
import { Head } from '@inertiajs/inertia-vue3'
</script>

<template>
  <Head>
    <title>Page Title</title>
     <meta name="description" content="Page Description" />
  </Head>
</template>

Hier is nog een voorbeeld uit de online documentatie van Inertia:


// Layout.vue

import { Head } from '@inertiajs/inertia-vue3'

<Head>
  <title>My app</title>
  <meta head-key="description" name="description" content="This is the default description" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
</Head>

// About.vue

import { Head } from '@inertiajs/inertia-vue3'

<Head>
  <title>About - My app</title>
  <meta head-key="description" name="description" content="This is a page specific description" />
</Head>

Formulieren en formulierhelper

Het is mogelijk om een standaard formulieraanvraag in te dienen terwijl je Inertia gebruikt. Dit resulteert echter in een refresh van de hele pagina.

Met Inertia kunnen gebruikers formulierverzoeken indienen, waardoor de pagina niet meer ververst hoeft te worden. Zodra het formulier met Inertia is verzonden, wordt het aan de serverzijde afgehandeld, zodat je de gebruiker terug kunt leiden naar dezelfde pagina (of een geheel andere pagina).

Inertia maakt ons leven gemakkelijker bij het maken en verzenden van formulieren. Hier is een voorbeeld van hoe je het kunt gebruiken met Vue.js 3 composition API:


<script setup>
  import { useForm } from "@inertiajs/inertia-vue3";

  const form = useForm({
    email: null,
    password: null,
  });
</script>

<template>
  <form @submit.prevent="form.post('kinsta/login')">
    
    <input type="text" v-model="form.email" />
    
    <input type="password" v-model="form.password" />
    
    <button type="submit">Login</button>
  </form>
</template>

Je kunt het formulier indienen met GET, POST, PUT, PATCH en DELETE.


<script setup>
  import { useForm } from "@inertiajs/inertia-vue3";

  const form = useForm({
    email: null,
    password: null,
  });

  const submit = () => {
    form.post("kinsta/login");
  };
</script>

<template>
  <form @submit.prevent="submit()">
    
    <input type="text" v-model="form.email" />
    
    <input type="password" v-model="form.password" />
    
    <button type="submit">Login</button>
  </form>
</template>

De formulierhelper van Inertia biedt ook een paar nuttige properties, zoals de property processing die verandert in true zodra het formulier begint te verwerken. Dit kan worden gebruikt om verzendknoppen uit te schakelen terwijl het formulier wordt verwerkt, om meerdere inzendingen te voorkomen:


<button type="submit" :disabled="form.processing">Submit</button>

Je kunt ook preserveState, preserveScroll en event callbacks gebruiken met het formulier, wat handig is bij het toevoegen van extra opties aan het formulier:


form.post('kinsta/login, {
  preserveScroll: true,
  onSuccess: () => form.reset('password'),
})

Toestand onthouden met Inertia.js

Stel dat een gebruiker een formulier invult op je website en besluit weg te navigeren naar een andere pagina voordat hij het formulier verzendt. Als ze terugkeren naar de formulierpagina, wordt de invoer van de gebruiker gereset.

Gelukkig biedt Inertia de functie useRemember, waarmee je de formulierinvoer van de gebruiker in de geschiedenisstatus kunt opslaan en bij de geschiedenisnavigatie weer kunt herstellen.

Je kunt deze feature gebruiken door hem te importeren uit Inertia en toe te passen op je formulier:


import { useRemember } from '@inertiajs/inertia-vue3'

export default {
  setup() {
    const form = useRemember({
        first_name: null,
        last_name: null,
    })

    return { form }
  },
}

Als je een pagina hebt met veel formulieren die de feature useRemember gebruiken, moet elk onderdeel een unieke sleutel hebben, zodat Inertia weet welke gegevens naar elk onderdeel moeten worden hersteld:


const form = useRemember({
        first_name: null,
        last_name: null,
    }, 'Users/Create')

We hoeven de feature useRemember niet te gebruiken als we de formulierenhulp van Inertia gebruiken. Inertia zal de toestand van de formulierinvoer automatisch onthouden, dus we hoeven alleen maar een unieke identificatiecode op te geven:


import { useForm } from '@inertiajs/inertia-vue3'

const form = useForm('CreateUser', data)

Het aardige van deze functionaliteit is dat je alle gegevens in je applicatie handmatig kunt onthouden. Dit kan ook handig zijn om gegevens van een diep geneste component door te geven aan de hoofdcomponent:


import { Inertia } from '@inertiajs/inertia'

// DeeplyNestedComponent.vue
Inertia.remember(data, 'my-key')

// MainComponent.vue
let data = Inertia.restore('my-key')

Bestanden uploaden

Inertia detecteert of het formulier bestanden bevat en, zo ja, transformeert de aanvraaggegevens naar het formData object, wat altijd vereist is. Dus als je een formulier hebt dat een naam en een avatar bevat, zal Inertia het formulier behandelen als multipart/form-data.

Validatie en fouten

Als een gebruiker een formulier indient met onjuiste waarden en het wordt naar de server gestuurd voor validatie, dan stuur je de gebruiker terug naar de formulierpagina met validatiefouten uit de sessie. Inertia vangt fouten uit de sessie op en slaat ze op als paginaprops.

Omdat props reactief zijn, verschijnen ze als de formulierverzending voltooid is. Om Inertia het bestaan van fouten te laten ontdekken, houdt deze page.props.errors in de gaten.

Zodra het fouten heeft gevonden, geeft het een onError() callback in plaats van onSuccess().

Hier is een voorbeeld met Vue 3 om je te helpen het concept te begrijpen:


const submit = () => {
    form.post("kinsta/login", {
        onError: () => {
            return "Hi! , the server returned an error and Inertia saved it as a prop. Do as you like with me"
        },
        onSuccess: () => {
            return "Wohoo!!"
        }
    }
    );
  };

Het weergeven van fouten is niets meer dan ze definiëren als props en ze voorwaardelijk te laten weergeven in je HTML:


<script setup>
  defineProps({
    errors: Object,
  });

//
</script>

<template>
  <form @submit.prevent="submit()">
    //
    <div v-if="errors.email">{{ errors.email }}</div>
  </form>
</template>

Als je Inertia gebruikt, hoef je je geen zorgen te maken over oude invoergegevens in geval van fouten. Zodra Inertia detecteert dat de gebruiker is doorgestuurd naar de pagina met fouten, behoudt het automatisch de oude toestand van de component voor POST, PUT, PATCH en DELETE.

Gedeeltelijk herladen met Inertia.js

De gedeeltelijke herlaadfunctie van Inertia is uitstekend, omdat het alleen een geselecteerde component op de pagina opnieuw laadt in plaats van de hele dataset opnieuw van de server op te halen. Dit tilt de optimalisatie van je applicatie naar een hoger niveau. Je kunt ook de volgende link bezoeken om meer te leren over hoe je de prestaties van je Laravel applicatie kunt optimaliseren.

Gedeeltelijk herladen kan worden uitgevoerd door Inertia’s only property te gebruiken:


import { Inertia } from '@inertiajs/inertia'

Inertia.visit(url, {
  only: ['users'],
})

Externe redirects met Inertia.js

Subdomein routing, of externe redirect, is een van de meest frustrerende uitdagingen bij SPA’s. Het is irrationeel om te verwachten dat je applicatie een single-page applicatie blijft terwijl je ook een ander domein bezoekt.

Het kan nodig zijn om een Inertia verzoek om te leiden naar een externe website of zelfs een ander niet-Inertia endpoint in je app. Dit is mogelijk via een door de server geïnitieerd window.location bezoek:


return Inertia::location($url);

Als je de console opent tijdens het testen hiervan, zul je zien dat de respons 409 conflict teruggeeft. Deze respons bevat de URL in de X-Inertia-Location header, die Inertia aan de clientzijde zal detecteren en automatisch het bezoek zal uitvoeren.

Werken met Inertia.js

Werken met Inertia is vergelijkbaar met werken aan een serverzijde applicatie, met de uitzondering dat het een volledig reactieve single-page applicatie is. Je zou in staat moeten zijn om je routes te definiëren, controllers aan te passen, en een view terug te sturen voor Inertia om naar je frontendframework te sturen.

Laravel routes en Inertia.js

Laravel routing is niet iets dat je wilt opgeven bij het ontwikkelen van je applicatie; het stelt je in staat om snel de meest complexe routes te construeren, en er zijn genoeg gratis en betaalde Laravel resources die je kunnen helpen om meer te leren over Laravel en hoe routing werkt.

Het mooie hier is dat je geen Vue Router of React Router nodig hebt om eenvoudige client-side routing uit te voeren, omdat Inertia zijn eigen routingsysteem heeft dat werkt met Laravel routing. Als de opdracht geen backendgegevens nodig heeft, kun je de routerhelper gebruiken om rechtstreeks naar een component te routen.


Route::inertia('/home', 'HomeComponent');

public function index()
    {
    return Inertia::render('Users/Index', [
        'users' => User::all();
        'create_url' => URL::route('users.create'),
    ]);
}

Voordat we verder gaan, willen we je kennis laten maken met DevKinsta, een krachtige tool voor developers, ontwerpers en webbureaus waarmee ze WordPress webapps met één of meerdere pagina’s kunnen bouwen. Gelukkig kan WordPress geïntegreerd worden met Laravel met behulp van het Corcel pakket. Als je een Laravel app bouwt met WordPress integratie, bekijk dan Kinsta APM Tool voor buitengewone prestatiebewaking.

Redirects

Je moet de gebruiker altijd omleiden naar het juiste pad dat overeenkomt met het oorspronkelijke verzoek. Als een gebruiker bijvoorbeeld naar store eindpoint gaat om een bericht in te dienen, zorg er dan voor dat je de klant omleidt naar GET eindpoint misschien naar de berichtroute.


public function store()
{
    Post::create(
        Request::validate([
            'title' => ['required'],
            'body' => ['required'],
        ])
    );

    // redirect the user to the posts show page
    return Redirect::route('posts.show');
}

Nadelen van het gebruik van Inertia.js

Tot nu toe hebben we ons gericht op de verschillende voordelen van het gebruik van Inertia. Maar zoals bij elke tool heeft Inertia ook nadelen.

  • De gebruiker moet basiskennis hebben van Vue of React.
  • Omdat modelgegevens volledig kunnen worden doorgegeven aan de clientzijde, moet de gebruiker ervoor zorgen dat de relevante gegevens expliciet worden geretourneerd aan de frontend.
  • API’s moeten opnieuw gemaakt worden als de webapplicatie ooit een Android of iOS applicatie krijgt.

Moet je Inertia.js gebruiken?

Het antwoord op de vraag of je Inertia wel of niet moet gebruiken is ja, als je een single-page, server-side, SEO-driven moderne app wilt bouwen.

Je kunt meer te weten komen door de officiële Inertia.js website te bezoeken en de documentatie te lezen.

Samenvatting

Client-side  apps en SPA’s worden steeds populairder naarmate webtechnologieën zich ontwikkelen, terwijl traditionele server-side applicaties steeds meer op de achtergrond raken. Meer dan ooit is het belangrijk om de juiste tools bij de hand te hebben.

Inertia is een fantastische moderne benadering of oplossing voor server-side developers om single-page apps te bouwen. Het lost enorm veel problemen op en bespaart veel tijd.

Zoals we in ons artikel bespraken, ondersteunt Inertia nu server-side rendering, wat het naar een heel nieuw niveau tilt door developers in staat te stellen SEO-driven SPA’s te maken.

Inertia krijgt daarnaast veel liefde van de community. De ontwikkeling wordt gesponsord door Laravel Forge, Laracasts en een aantal andere goede organisaties. Daardoor is Inertia een betrouwbare tool die in de toekomst verbeterd en onderhouden zal worden voor Laravel developers, vooral omdat de vraag naar Laravel coders blijft groeien.

En als je op zoek bent naar de volgende thuisbasis voor je door Intertia aangedreven project, kijk dan eens naar Kinsta’s Applicatie Hosting.