Applikationer med en enda sida (SPA) har blivit det moderna sättet att skapa webbapplikationer. Inertia.js är ett ledande verktyg som gör det möjligt för utvecklare att skapa SPA: er med både klient- och serverside-rendering.

I den här artikeln så tittar vi på hur Inertia gör det enkelt att konstruera SPA: er och hur det löser många andra problem för utvecklare. Vi kommer även att ta upp de viktigaste funktionerna i verktyget.

Men innan vi börjar så ska vi först försäkra oss om att vi förstår hur server- och klientsidaapplikationer fungerar.

Vad är serverbaserad rendering?

Serverside-rendering (SSR) är när en applikation kan rendera eller visa webbsidans innehåll på servern i stället för i webbläsaren. När en användare försöker besöka example.com gör webbläsaren en förfrågan till servern och ber om all nödvändig information för att visa den specifika webbsidan. Servern svarar omedelbart genom att ge webbläsaren en fullständigt renderad sida.

Sökmotorer ingriper och indexerar information som tillhandahålls av servern innan den når webbläsaren; detta kallas sökmotoroptimering (SEO). Webbläsaren löser sedan upp JavaScript-innehållet och webbsidan visas för användaren.

Visning av innehåll som har renderats på serversidan.
Visning av innehåll som har renderats på serversidan.

Problemet med SSR-metoden är att det tar lång tid att ladda in en fullt renderad sida från servern. Detta skapar inte en trevlig användarupplevelse. Det är därför som utvecklare överväger SPA: er och rendering på klientsidan.

Vad är Klientside rendering?

Klientside-rendering gör att webbläsaren får allt som den behöver för att rendera webbsidan från klientsidan i stället för att ta emot en helt renderad sida från servern. När sidan är laddad så skickar webbläsaren inga andra förfrågningar till servern. Detta gör att surfupplevelsen blir extremt snabb.

Visning av innehåll som har renderats på klientsidan.
Visning av innehåll som har renderats på klientsidan.

Rendering på klientsidan bidrog till skapandet av SPA: er och revolutionerade webben. Du kan skapa en webbplats som inte kräver att sidan laddas om. Detta gäller oavsett hur många länkar som du klickar på. Det gör det enkelt för användaren att navigera på webbplatsen.

Även om SPA: er är fantastiska så har detta tillvägagångssätt en hel del komplexitet och problem som vi kommer att ta upp idag. Inertia tar itu med majoriteten av dessa problem genom att effektivt utnyttja serverside-ramverk. Den kombinerar de bästa egenskaperna hos både server- och klientsidiga appar.

Vad är Inertia.js?

Inertia är inte ett ramverk för JavaScript. Det är istället en strategi eller teknik för att utveckla SPA: er. Den gör det möjligt för utvecklaren att använda nuvarande serverbaserade ramverk för att bygga ett modernt SPA. Detta kan göras utan den vanliga komplexiteten.

Inertia har utformats för att följa med, inte ersätta, de ramverk som du redan använder. Se det som en hjälpsam allierad som hjälper dig att utföra uppgifter snabbare och effektivare. Det stöder för närvarande tre frontend-ramverk (Vue, React och Svelte) för rendering på klientsidan. Det stöder även två backend-ramverk (Laravel och Rails) för rendering på serversidan.

För de flesta Laravel-utvecklare så är Inertia en av de mest tillförlitliga teknikerna för att konstruera SPA:er. Detta beror på att den gör det möjligt att både ansluta frontend- och backend-ramverk.

Hur fungerar Inertia.js?

Inertia liknar Vue Router i det avseendet att det gör det möjligt att flytta mellan sidor utan att behöva ladda om hela sidan. Ramverket fungerar dock i synk med ditt ramverk på serversidan. Detta är möjligt tack vare Link, en wrapper för den vanliga ankartaggen. När man klickar på Link så fångar Inertia upp klickhändelsen och skickar en XHR-förfrågan till servern. Som ett resultat så känner servern igen att detta är en Inertia-förfrågan och returnerar ett JSON-svar. Svaret innehåller JavaScript-komponentens namn och data. Efter detta så tar Inertia på magisk väg bort onödiga komponenter och ersätter dem med de som krävs för att besöka den nya sidan och uppdaterar historikstatusen.

En djupdykning i Inertia.js funktionalitet

När en besökare besöker example.com för första gången så utför webbläsaren en vanlig helsidesförfrågan. Servern returnerar ett fullständigt HTML-svar som om Inertia inte fanns. HTML-svaret innehåller alla webbplatstillgångar (CSS, JavaScript), men innehåller även en extra tillgång för Inertia. Tillgången är roten div med attributet data-page som innehåller JSON-data för den första sidan. Inertia använder sedan dessa JSON-data för att starta frontend-ramverket och visa den första sidan.

Inertia.js: Svar för besök på den första sidan.
Inertia.js: Svar för besök på den första sidan.

När appen väl har startat upp så kommer varje sökväg som användaren besöker inom samma domän med hjälp av Link att vara en XHR-förfrågan med X-Inertia -huvudet. Detta talar om för servern att detta är en Inertia-förfrågan.

Återkopplingen kommer att komma som ett JSON-svar med sidans innehåll, snarare än ett fullständigt HTML-svar som vid det första besöket.

Inertia.js: Svar på efterföljande besök på en route.
Inertia.js: Svar på efterföljande besök på en route.

Vilka problem löser Inertia.js?

Inertia löser ett stort antal problem för webbutvecklare. Målet med att skapa Inertia var att ge snabba och effektiva lösningar på all den komplexitet som följer med utformningen av en SPA.

SPA-komplexitet

Om utvecklare skulle bygga en SPA utan Inertia så skulle de behöva skapa REST- eller GraphQL-API: er. De skulle sedan behöva skydda dem med någon form av autentiseringsmetod. Som ett resultat av detta så skulle det krävas att man skapar ett system för tillståndshantering i frontend, bland många andra saker.

Inertia utformades för att hjälpa utvecklare att omvandla sina serverbaserade applikationer som körs på backend-servern till en JavaScript-applikation med en enda sida. Detta utan att behöva gå igenom alla de komplexa problem som följer med att bygga SPA: er.

Att skapa en SPA med hjälp av Inertia liknar skapandet av en serverside-rendered app. Du skapar kontrollanter, gör förfrågningar till databasen för att få de nödvändiga uppgifterna och returnerar sedan resultaten till vyerna.

Nyckeln här är att vyerna är JavaScript-komponenter. Detta innebär att du hämtar data från servern och att Inertia sedan samarbetar med frontend-ramverket för att visa sidan med data som en JavaScript-fil. Detta eliminerar behovet av att skapa API: er.

Autentisering

Eftersom Inertia förser applikationen med data och svar från backend så kommer den helt enkelt att använda det autentiseringssystem som du har på serversidan. Detta innebär att du inte behöver oroa dig för autentisering på klientsidan. Du har istället ett sessionsbaserat autentiseringssystem som synkroniseras med ditt autentiseringssystem på serversidan.

SEO-frågor

Vi förklarade detta tidigare angående serverside-rendering men kan ta det igen. Sökmotorerna avlyssnar serverns svar till webbläsaren för att indexera webbsidans HTML-innehåll. När det gäller SPA så så kommer sökmotorerna att ha svårt att identifiera sidans innehåll. Detta beror på att servern antingen svarar med JavaScript-komponenter eller JSON-data.

Men Inertia löste detta problem genom att införa funktionen för serverside-rendering (SSR) som du kan lägga till i din applikation. Inertia använder Node.js-miljön som en utlösare för att konvertera JSON-datasvaret till HTML.

För att illustrera detta bättre så kan du tänka dig att Inertia sitter mellan servern och webbläsaren och tittar på. När servern tar emot en Inertia-förfrågan och returnerar ett JSON-svar så upptäcker Inertia att det finns en Node.js-server. Ramverket omvandlar JSON-svaret till HTML och returnerar det, vilket gör att sökmotorerna kan indexera sidan som om applikationen inte vore en SPA.

Inertia tillhandahåller även en Head -komponent som gör det möjligt att lägga till en titel och metadata till din sida:


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

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

Här är ett annat exempel från Inertias online-dokumentation:


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

Formulär och Formulärhjälpare

Det är möjligt att skicka in ett standardformulär när man använder Inertia. Om du gör detta så kommer dock hela sidan att uppdateras.

Inertia gör det möjligt för användarna att göra formulärförfrågningar med hjälp av Inertia. Som ett resultat så behöver sidan inte uppdateras. När formuläret skickas in med Inertia så hanteras det på serversidan. Detta gör att du kan omdirigera användaren tillbaka till samma sida (eller en helt annan sida).

Inertia gör våra liv enklare när vi skapar och skickar in formulär. Här är ett exempel på hur du kan använda 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 skicka in formuläret med GET, POST, PUT, PATCH och 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 formulärhjälpare erbjuder även några användbara egenskaper, exempelvis egenskapen processing. Den förvandlas till true när formuläret börjar bearbetas. Detta kan användas för att inaktivera inlämningsknapparna medan formuläret bearbetas för att förhindra flera inlämningar:


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

Du kan även använda preserveState, preserveScroll och event callbacks med formuläret. Detta kan vara till hjälp när du lägger till ytterligare alternativ till formuläret:


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

Minns tillstånd med Inertia.js

Låt oss säga att en användare fyller i ett formulär på din webbplats och bestämmer sig för att navigera vidare till en annan sida innan han eller hon skickar in formuläret. När de återvänder till formulärsidan så kommer användarens formulärinmatning att återställas.

Som tur är så har Inertia funktionen useRemember. Den gör att du kan spara användarens formulärinmatningar i historiktillståndet och återställa dem vid historisk navigering.

Du kan använda den här funktionen genom att importera den från Inertia och tillämpa den på ditt formulär:


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

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

    return { form }
  },
}

Om du har en sida med många formulär som använder funktionen useRemember så måste varje komponent ha en unik nyckel. Då vet Inertia vilka data som ska återställas i varje komponent:


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

Vi behöver inte använda funktionen useRemember när vi använder Inertia’s formulärhjälpare. Inertia kommer att komma ihåg formulärinmatningens tillstånd automatiskt, så vi behöver bara ange en unik identifierare:


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

const form = useForm('CreateUser', data)

Det fina med den här funktionen är att du kan komma ihåg alla data i din applikation manuellt. Detta kan även vara användbart för att överföra data från en djupt inbäddad komponent till huvudkomponenten:


import { Inertia } from '@inertiajs/inertia'

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

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

Uppladdning av filer

Inertia upptäcker om formuläret innehåller filer och omvandlar i så fall förfrågningsdata till formData -objektet, vilket alltid krävs. Om du har ett formulär som innehåller ett namn och en avatar så behandlar Inertia formuläret som multipart/form-data.

Validering och fel

Vi tänker oss att en användare skickar in ett formulär med felaktiga värden och det skickas till servern för validering. Då returnerar du användaren till formulärsidan med en flash av valideringsfel i sessionen. Inertia fångar upp fel från sessionen och sparar dem som sidprops.

Eftersom props är reaktiva så visas de när formulärsändningen är klar. För att Inertia ska kunna upptäcka förekomsten av fel så håller den ett öga på page.props.errors.

När den har hittat fel så ger den sedan en onError()-callback i stället för onSuccess().

Här är ett exempel med Vue 3 för att hjälpa dig att förstå 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!!"
        }
    }
    );
  };

Det är lika enkelt att visa fel som att definiera dem som props och visa dem villkorligt 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 använder Inertia så behöver du inte oroa dig för gammal inmatningsdata vid eventuella fel. När Inertia upptäcker att användaren har omdirigerats till sidan med fel, bevarar den automatiskt komponentens gamla tillstånd för POST, PUT, PATCH och DELETE.

Partiell omdirigering med Inertia.js

Inertias funktionalitet för partiell omladdning är utmärkt eftersom det bara laddar om en vald komponent på sidan. Det hämtar alltså inte hela datamängden från servern igen. Detta tar din applikationsoptimering till nästa nivå. Du kan även besöka följande länk för att lära dig mer om hur du optimerar din Laravel-applikation’s prestanda.

Partiell omladdning kan utföras genom att använda Inertia’s egenskap only:


import { Inertia } from '@inertiajs/inertia'

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

Externa omdirigeringar med Inertia.js

Underdomäner, eller externa omdirigeringar, är en av de mest frustrerande utmaningarna med SPA: er. Det är irrationellt att förvänta sig att din applikation ska förbli en enkelsides-applikation samtidigt som du besöker en annan domän.

Det kan vara nödvändigt att omdirigera en Inertia-förfrågan till en extern webbplats. Till och med till en annan slutpunkt som inte tillhör Inertia i din app. Detta är möjligt genom ett serverinitierat besök på window.location:


return Inertia::location($url);

Om du öppnar konsolen när du testar detta så kommer du att se att den returnerar 409 conflict. Svaret innehåller webbadressen i X-Inertia-Location-huvudet, vilket Inertia kommer att upptäcka på klientsidan och utföra besöket automatiskt.

Hur man arbetar med Inertia.js

Att arbeta med Inertia liknar arbetet med en applikation på serversidan. Undantaget är att det är en helt reaktiv enkelsidesapplikation. Du bör kunna definiera dina routes, anpassa kontrollanter och returnera en vy som Inertia kan skicka till ditt frontend-ramverk.

Laravel-routes och Inertia.js

Laravel-routing är inget som du bör ge upp när du utvecklar din applikation. Det gör att du snabbt kan konstruera de mest komplexa routes, och det finns gott om kostnadsfria och betalda Laravel-resurser där ute som kan hjälpa dig att lära dig mer om Laravel och hur routing fungerar.

Det fina här är att du inte behöver Vue Router eller React Router för att utföra enkel routing på klientsidan. Inertia har nämligen sitt eget routing-system som fungerar med Laravel-routing. Om jobbet inte kräver några backend-data så kan du använda routerhjälpen för att dirigera direkt till en komponent.


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

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

Innan vi går vidare så vill vi presentera DevKinsta. Det är ett kraftfullt verktyg för utvecklare, designers och agenturer som gör det möjligt att skapa WordPress-webbappar med en eller flera sidor. WordPress kan lyckligtvis integreras med Laravel med hjälp av Corcel-paketet. Om du bygger en Laravel-app med WordPress-integrering, kolla in Kinsta APM-verktyget för en extraordinär prestandaövervakning.

Omdirigeringar

Du bör alltid omdirigera användaren till rätt sökväg som motsvarar det ursprungliga begärandet. Om en användare exempelvis skickar in ett inlägg till store-slutpunkten, se till att omdirigera kunden till GET-slutpunkten och kanske till post-routen.


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

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

Nackdelar med att använda Inertia.js

Hittills har vi fokuserat på flera fördelar med att använda Inertia. Men som med alla verktyg så har Inertia också nackdelar.

  • Användaren måste ha grundläggande kunskaper om Vue eller React.
  • Eftersom modelldata kan skickas helt och hållet till klientsidan så måste användaren se till att explicit returnera relevanta data till frontend.
  • API: er måste återskapas om webbapplikationen någon gång ska ha en Android- eller iOS-applikation.

Bör du använda Inertia.js?

För att svara på frågan om du bör använda Inertia eller inte är svaret ja. Iallafall om du vill bygga en enkelsidig, serverbaserad, SEO-driven modern app.

Du kan lära dig mer genom att besöka den officiella webbplatsen för Inertia.js och läsa dokumentationen.

Sammanfattning

Klientbaserade appar och SPA: er blir alltmer populära i takt med att webbtekniken utvecklas. Traditionella serverbaserade program har börjat falla bort. Nu är det med andra ord viktigare än någonsin att ha rätt verktyg till hands.

Inertia är ett fantastiskt modernt tillvägagångssätt eller en lösning för utvecklare på serversidan för att bygga enkelsidiga appar. Det löser så många problem och sparar så mycket tid.

Som vi diskuterade i vår artikel så har Inertia numera stöd för serverside-rendering. Detta tar verktyget till en helt ny nivå genom att låta utvecklare skapa SEO-drivna SPA: er.

Inertia får även mycket kärlek från sitt community. Utvecklingsarbetet sponsras av Laravel Forge, Laracasts och ett antal andra fina organisationer. Som ett resultat av detta så är Inertia ett pålitligt verktyg. Det kommer att förbättras och underhållas i framtiden för Laravel-utvecklare, särskilt eftersom efterfrågan på Laravel-kodare fortsätter att öka.

Och om du letar efter nästa hem för ditt Intertia-drivna projekt så kan du kolla in Kinsta’s erbjudanden om applikationshosting.