Single-page applications (SPA’er) er blevet den moderne måde at skabe webapplikationer på, og Inertia.js er et førende værktøj, der gør det muligt for udviklere at skabe SPA’er med både klient- og server-side rendering.

I denne artikel vil vi se på, hvordan Inertia gør det til en leg at konstruere SPA’er, og hvordan det løser mange andre problemer for udviklere. Vi vil også dække de vigtigste funktioner i værktøjet.

Men før vi begynder, skal vi først sikre os, at vi forstår, hvordan server- og klientsideapplikationer fungerer.

Hvad er server-side rendering?

Server-side rendering (SSR) er, når et program kan rendere eller vise websideindhold på serveren i stedet for i browseren. Når en bruger forsøger at besøge example.com, sender browseren en anmodning til serveren og beder om alle de nødvendige oplysninger til visning af denne specifikke webside, og serveren svarer straks ved at give browseren en fuldt gengivet side.

Søgemaskinerne griber ind og indekserer de oplysninger, der leveres af serveren, før de når frem til browseren; dette kaldes søgemaskineoptimering (SEO). Browseren opløser derefter JavaScript-indholdet, og websiden vises for brugeren.

Visning af indhold, der er gengivet på serversiden.
Visning af indhold, der er gengivet på serversiden.

Problemet med SSR-tilgangen er, at det tager lang tid at indlæse en fuldt renderet side fra serveren, hvilket ikke giver en behagelig brugeroplevelse. Derfor overvejer udviklere SPA’er og rendering på klientsiden.

Hvad er client-side rendering?

Client-side rendering giver browseren mulighed for at få alt det, den har brug for til at rendere websiden fra klientsiden i stedet for at modtage en fuldt renderet side fra serveren. Når siden er indlæst, sender browseren ikke andre anmodninger til serveren, hvilket gør browsing-oplevelsen ekstremt hurtig.

Et diagram, der viser stadierne af gengivelse på klientsiden.
Visning af indhold, der er gengivet på klientsiden.

Rendering på klientsiden hjalp med at skabe SPA’er, hvilket revolutionerede internettet. Du kan oprette et websted, der ikke kræver genindlæsning af siden, uanset hvor mange links du klikker på. Det gør det nemt for brugeren at navigere gennem hjemmesiden.

Selv om SPA’er er fantastiske, har denne tilgang en masse kompleksitet og problemer, som vi vil dække i dag. Inertia løser de fleste af disse problemer ved effektivt at udnytte server-side frameworks. Det kombinerer de bedste funktioner fra både server- og klientside apps.

Hvad er Inertia.js?

Inertia er ikke en JavaScript-framework. Det er i stedet en strategi eller teknik til udvikling af SPA’er. Den gør det muligt for udvikleren at udnytte de nuværende server-side frameworks til at bygge en moderne SPA uden den kompleksitet, der følger med den.

Inertia er designet til at ledsage og ikke erstatte de frameworks, du allerede bruger. Betragt det som en hjælpsom allierede, der hjælper dig med at udføre opgaverne hurtigere og mere effektivt. Den understøtter i øjeblikket tre frontend-frameworks (Vue, React og Svelte) til klientside-rendering og to backend-rammer (Laravel og Rails) til server-side-rendering.

For de fleste Laravel-udviklere er Inertia en af de mest pålidelige teknikker til at konstruere SPA’er, da den giver dem mulighed for at forbinde både frontend- og backend-frameworks.

Hvordan fungerer Inertia.js?

Inertia ligner Vue Router, idet det giver dig mulighed for at flytte mellem sider uden at skulle genindlæse hele siden. Inertia fungerer dog i synkronisering med dit server-side framework. Dette er muligt med Link, en wrapper for standard ankertagget. Når der klikkes på en Link, opfanger Inertia klikhændelsen og sender en XHR-forespørgsel til serveren, hvilket får serveren til at genkende, at der er tale om en Inertia-forespørgsel, og returnere et JSON-svar. Dette svar indeholder JavaScript-komponentens navn og data, hvorefter Inertia på magisk vis fjerner unødvendige komponenter og erstatter dem med dem, der er nødvendige for at besøge den nye side, og opdaterer historikstatus.

Et dybt dyk ind i Inertia.js-funktionaliteten

Når en besøgende første gang besøger example.com, udfører browseren en standardanmodning om en hel side, og serveren returnerer et fuldstændigt HTML-svar, som om Inertia ikke eksisterede. Dette HTML-svar indeholder alle webstedets aktiver (CSS, JavaScript), men det indeholder også et ekstra aktiv for Inertia, som er roden div med data-page-attributten, der indeholder JSON-data for den oprindelige side. Inertia bruger derefter disse JSON-data til at kickstarte frontend-framework og vise startsiden.

Diagram, der viser handlinger ved første besøg på en webside ved brug af Inertia.js.
Inertia.js: Svar på det første sidebesøg

Når appen er startet op, vil hver rute, som brugeren besøger inden for det samme domæne ved hjælp af Link, være en XHR-forespørgsel med X-Inertia-headeren. Dette fortæller serveren, at der er tale om en Inertia-forespørgsel.

Tilbagemeldingen vil komme som et JSON-svar med sidens indhold i stedet for et komplet HTML-svar som ved det første besøg.

Diagram, der viser handlinger ved adgang til andre ruter ved brug af Inertia.js.
Inertia.js: Svar på efterfølgende rutebesøg.

Hvilke problemer løser Inertia.js?

Inertia løser en lang række problemer for webudviklere. Målet med at skabe Inertia var at give hurtige og effektive løsninger på al den kompleksitet, der følger med design af en SPA.

SPA-kompleksiteter

Hvis udviklere skulle bygge en SPA uden Inertia, ville de være nødt til at oprette REST- eller GraphQL-API’er og beskytte dem med en eller anden form for godkendelsesmetode, hvilket blandt mange andre ting ville kræve oprettelse af et front-end-state-management-system.

Inertia blev designet til at hjælpe udviklere med at omdanne deres serversideapplikationer, der kører helt på backend-serveren, til en JavaScript-applikation med én side uden at skulle gennemgå alle de kompleksiteter, der følger med opbygningen af SPA’er.

Oprettelse af en SPA ved hjælp af Inertia svarer til at oprette en server-side rendered app. Du opretter controllere, foretager forespørgsler til databasen for at få de nødvendige data og returnerer derefter resultaterne til visningerne.

Nøglen her er, at visningerne er JavaScript-komponenter. Det betyder, at du får dataene fra din server, hvorefter Inertia arbejder sammen med frontend-framework for at vise siden med dataene som en JavaScript-fil, hvilket eliminerer behovet for at oprette API’er.

Autentifikation

Da Inertia forsyner applikationen med data og svar fra backenden, vil den simpelthen bruge det autentifikationssystem, du har på serversiden. Det betyder, at du ikke behøver at bekymre dig om autentificering på klientsiden – du vil i stedet have et sessionsbaseret autentificeringssystem, der synkroniseres med dit autentificeringssystem på serversiden.

SEO-problemer

Som tidligere forklaret for server-side rendering, opsnapper søgemaskinerne serverens svar til browseren for at indeksere websidens HTML-indhold. I tilfælde af en SPA vil søgemaskinerne have svært ved at identificere sidens indhold, da serveren vil svare med enten JavaScript-komponenter og JSON-data.

Men Inertia løste dette problem ved at introducere funktionen SSR (Server-side rendering), som du kan tilføje til din applikation. Inertia bruger Node.js-miljøet som en udløser til at konvertere JSON-datasvaret til HTML.

For at illustrere dette bedre kan du forestille dig Inertia, der sidder mellem serveren og browseren og kigger på. Når serveren modtager en Inertia-forespørgsel og returnerer et JSON-svar, registrerer Inertia eksistensen af en Node.js-server, omdanner JSON-svaret til HTML og returnerer det, så søgemaskinerne kan indeksere siden, som om appen ikke var en SPA.

Inertia indeholder også en Head-komponent, som giver dig mulighed for at tilføje en titel og metadata til din side:


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

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

Her er et andet eksempel fra Inertias onlinedokumentation:


// 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>

Formularer og formularhjælper

Det er muligt at indsende en standardformularanmodning, mens man bruger Inertia. Det vil dog resultere i en opdatering af hele siden.

Inertia giver brugerne mulighed for at indgive formularforespørgsler ved hjælp af Inertia, hvilket fjerner muligheden for sideopfriskning. Når formularen er indsendt med Inertia, bliver den håndteret server-side, hvilket gør det muligt for dig at omdirigere brugeren tilbage til den samme side (eller en helt anden side).

Inertia gør vores liv lettere, når vi opretter og indsender formularer. Her er et eksempel på, hvordan du kan bruge det med 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>

Du kan indsende formularen med GET, POST, PUT, PATCH og 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>

Inertias formularhjælper tilbyder også et par nyttige egenskaber som f.eks. processing-egenskaben, der bliver til true, når formularen begynder at blive behandlet. Dette kan bruges til at deaktivere indsendelsesknapper, mens formularen behandles, for at forhindre flere indsendelser:


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

Du kan også bruge preserveState, preserveScroll og event callbacks med formularen, hvilket vil være nyttigt, når du tilføjer yderligere muligheder til formularen:


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

Huskelse af tilstand med Inertia.js

Lad os sige, at en bruger udfylder en formular på dit websted og beslutter sig for at navigere væk til en anden side, før han sender den. Når de vender tilbage til formularens side, vil brugerens formularinput blive nulstillet.

Heldigvis tilbyder Inertia funktionen useRemember, som giver dig mulighed for at gemme brugerens formularinput i historikstatus og gendanne dem ved historiknavigation.

Du kan bruge denne funktion ved at importere den fra Inertia og anvende den på din formular:


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

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

    return { form }
  },
}

Hvis du har en side med mange formularer, der bruger funktionen useRemember, skal hver komponent have en unik nøgle, så Inertia ved, hvilke data der skal gendannes i hver komponent:


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

Vi behøver ikke at bruge useRemember-funktionen, når vi bruger Inertias formularhjælper. Inertia vil automatisk huske formularinputets tilstand, så vi skal blot angive en unik identifikator:


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

const form = useForm('CreateUser', data)

Det gode ved denne funktionalitet er, at du kan huske alle data i din applikation manuelt. Dette kan også være nyttigt til at videregive data fra en dybt indlejret komponent til hovedkomponenten:


import { Inertia } from '@inertiajs/inertia'

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

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

Filoverførsler

Inertia registrerer, om formularen indeholder filer, og hvis det er tilfældet, transformerer forespørgselsdataene til formData-objektet, hvilket altid er påkrævet. Så hvis du har en formular, der indeholder et navn og en avatar, vil Inertia behandle formularen som multipart/form-data.

Validering og fejl

Når en bruger indsender en formular med forkerte værdier, og den sendes til serveren til validering, returnerer du brugeren til formularens side med et blink af valideringsfejl i sessionen. Inertia opfanger fejl fra sessionen og gemmer dem som sideprops.

Da props er reaktive, vises de, når indsendelsen af formularen er afsluttet. For at Inertia kan opdage eksistensen af fejl, holder den øje med page.props.errors.

Når den har fundet fejl, leverer den derefter en onError() callback i stedet for onSuccess().

Her er et eksempel med Vue 3 for at hjælpe dig med at forstå konceptet:


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!!"
        }
    }
    );
  };

Visning af fejl er så let som at definere dem som props og vise dem betinget i din HTML:


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

//
</script>

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

Når du bruger Inertia, behøver du ikke at bekymre dig om gamle inputdata i tilfælde af fejl. Når Inertia registrerer, at brugeren er blevet omdirigeret til siden med fejl, bevarer den automatisk komponentens gamle tilstand for POST, PUT, PATCH og DELETE.

Delvise reloads med Inertia.js

Inertias funktionalitet til delvis genindlæsning er ganske enkelt fremragende, da den kun genindlæser en udvalgt komponent på siden i stedet for at hente hele datasættet fra serveren igen. Dette tager din applikationsoptimering til det næste niveau. Du kan også besøge følgende link for at få mere at vide om hvordan du optimerer din Laravel-applikations ydeevne.

Delvise genindlæsninger kan udføres ved hjælp af Inertia’s only egenskab:


import { Inertia } from '@inertiajs/inertia'

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

Eksterne omdirigeringer med Inertia.js

Underdomæne-routing, eller ekstern omdirigering, er en af de mest frustrerende udfordringer med SPA’er. Det er irrationelt at forvente, at din applikation forbliver en single-page applikation, mens du også besøger et andet domæne.

Det kan være nødvendigt at omdirigere en Inertia-forespørgsel til et eksternt websted eller endog et andet ikke-Inertia-slutpunkt i din app. Dette er muligt gennem et server-side-initieret window.location besøg:


return Inertia::location($url);

Hvis du åbner konsollen under afprøvning af dette, vil du opdage, at det returnerer 409 conflict. Dette svar indeholder URL’en i X-Inertia-Location-headeren, som Inertia vil registrere på klientsiden og automatisk udføre besøget.

Sådan arbejder du med Inertia.js

At arbejde med Inertia svarer til at arbejde med en server-side applikation, med den undtagelse at det er en fuldt reaktiv single-page applikation. Du bør være i stand til at definere dine ruter, tilpasse controllere og returnere en visning, som Inertia skal sende til din frontend-framework.

Laravel-ruter og Inertia.js

Laravel-routing er ikke noget, du ønsker at opgive, når du udvikler din applikation; det giver dig mulighed for hurtigt at konstruere de mest komplekse ruter, og der er masser af gratis og betalte Laravel-ressourcer derude, der kan hjælpe dig med at lære mere om Laravel og hvordan routing fungerer.

Det smukke her er, at du ikke behøver Vue Router eller React Router for at udføre simpel klient-side routing, fordi Inertia har sit eget routing-system, der fungerer med Laravel-routing. Hvis jobbet ikke kræver nogen backend-data, kan du bruge router-hjælperen til at route direkte til en komponent.


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

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

Før vi går videre, vil vi gerne præsentere dig for DevKinsta, et kraftfuldt værktøj til udviklere, designere og bureauer, der gør det muligt for dem at konstruere WordPress-webapps med en eller flere sider. Heldigvis kan WordPress integreres med Laravel ved hjælp af Corcel-pakken. Hvis du bygger en Laravel-app med WordPress-integration, skal du tjekke Kinsta APM Tool for ekstraordinær overvågning af ydeevne.

Omdirigerer

Du bør altid omdirigere brugeren til den korrekte sti, der svarer til den oprindelige anmodning. Hvis en bruger f.eks. sender til store endpoint for at indsende et indlæg, skal du sørge for at omdirigere kunden til GET endpoint måske til indlægsruten.


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

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

Ulemper ved at bruge Inertia.js

Indtil videre har vi fokuseret på de mange fordele ved at bruge Inertia. Men som med ethvert værktøj har Inertia også et par ulemper.

  • Brugeren skal have grundlæggende kendskab til Vue eller React.
  • Da modeldata kan overføres fuldstændigt til klientsiden, skal brugeren sørge for eksplicit at returnere de relevante data til frontend’en.
  • API’er skal genskabes, hvis webapplikationen på et tidspunkt skal have en Android- eller iOS-applikation.

Skal du bruge Inertia.js?

For at besvare spørgsmålet om, hvorvidt du bør bruge Inertia eller ej, er svaret ja, hvis du ønsker at bygge en enkeltsidet, server-side, SEO-drevet moderne app.

Du kan få mere at vide ved at besøge det officielle Inertia.js-websted og læse dokumentationen.

Opsummering

Klient-side apps og SPA’er bliver mere og mere populære i takt med udviklingen af webteknologier, mens server-side traditionelle applikationer er begyndt at falde på gulvet. Mere end nogensinde før er det vigtigt at have de rigtige værktøjer ved hånden.

Inertia er en fantastisk moderne tilgang eller løsning for server-side udviklere til at bygge single-page apps. Det løser så mange problemer og sparer dig så meget tid.

Som vi diskuterede i vores artikel, understøtter Inertia nu server-side rendering, hvilket tager det til et helt nyt niveau ved at give udviklere mulighed for at skabe SEO-drevne SPA’er.

Inertia modtager også en masse kærlighed fra fællesskabet. Udviklingsindsatsen er sponsoreret af Laravel Forge, Laracasts og en række andre fine organisationer. Som et resultat heraf er Inertia et pålideligt værktøj, der vil blive forbedret og vedligeholdt i fremtiden for Laravel-udviklere, især da efterspørgslen efter Laravel-kodere fortsætter med at vokse.

Og hvis du leder efter dit Intertia-drevne projekts næste hjem, kan du tjekke Kinsta’s tilbud om Applikation Hosting.