Norsk

Utforsk det transformative filbaserte rutingsystemet i Next.js' App Directory, som tilbyr forbedret organisering, ytelse og utvikleropplevelse for moderne webapplikasjoner.

Next.js App Directory: En filbasert rutingrevolusjon

Next.js har konsekvent flyttet grensene for webutvikling, og tilbyr utviklere kraftige verktøy og funksjoner for å bygge ytelsessterke, skalerbare og brukervennlige applikasjoner. Introduksjonen av App Directory representerer et betydelig sprang fremover, spesielt i sin innovative tilnærming til filbasert ruting. Denne artikkelen dykker dypt ned i App Directorys rutingsmekanisme, og utforsker dens fordeler, nøkkelkonsepter og praktiske implikasjoner for å bygge moderne webapplikasjoner med Next.js.

Forstå utviklingen av ruting i Next.js

Før App Directory, stolte Next.js på Pages Directory for ruting. Selv om den var effektiv, hadde denne tilnærmingen visse begrensninger. Pages Directory brukte et enkelt filbasert rutingsystem der hver fil i `pages`-mappen tilsvarte en rute. For eksempel ville `pages/about.js` bli mappet til `/about`-ruten.

Selv om den var enkel, manglet Pages Directory innebygd støtte for komplekse layouter, datahentingsstrategier og server-side renderingsmønstre, noe som ofte krevde at utviklere måtte implementere disse funksjonene manuelt. Videre kunne den tette koblingen mellom datahenting og komponentgjengivelse noen ganger føre til ytelsesflaskehalser.

App Directory løser disse begrensningene ved å introdusere et mer fleksibelt og kraftig rutingsystem bygget på React Server Components, Layouts og andre avanserte funksjoner. Det går utover en enkel fil-til-rute-mapping og tilbyr en mer deklarativ og sammensettbar tilnærming til å definere applikasjonsruter og layouter.

Introduksjon til App Directory: Et nytt paradigme for ruting

App Directory, som ligger i roten av Next.js-prosjektet ditt i `app`-mappen, introduserer en fundamentalt annerledes tilnærming til ruting. I stedet for å direkte mappe filer til ruter, bruker App Directory et konvensjonsbasert system der strukturen av mapper og spesialfiler bestemmer applikasjonens ruter.

Denne tilnærmingen gir flere sentrale fordeler:

Nøkkelkonsepter i App Directorys rutingsystem

For å effektivt kunne bruke App Directorys rutingsystem, er det essensielt å forstå nøkkelkonseptene som ligger til grunn for funksjonaliteten:

1. Rutesegmenter og mapper

Hver mappe i `app`-mappen representerer et rutesegment. Navnet på mappen tilsvarer stisegmentet i URL-en. For eksempel vil en `app/blog/posts`-mappestruktur bli mappet til `/blog/posts`-ruten.

Se for deg denne strukturen:

app/
  blog/
    posts/
      page.js

Denne strukturen definerer en rute på `/blog/posts`. Filen `page.js` i `posts`-mappen er rutesegmentkomponenten, som gjengir innholdet for den ruten.

2. `page.js`-filen: Gjengivelse av ruteinnhold

Filen page.js (eller page.tsx for TypeScript) er en spesiell fil som definerer innholdet som skal gjengis for et spesifikt rutesegment. Det er inngangspunktet for den ruten. Denne filen må eksportere en React-komponent som sin standardeksport.

Eksempel:

// app/blog/posts/page.js

export default function PostsPage() {
  return (
    <div>
      <h1>Blogginnlegg</h1>
      <p>Liste over blogginnlegg vil bli vist her.</p>
    </div>
  );
}

3. Layouts: Definere delt brukergrensesnitt

Layouts lar deg definere et brukergrensesnitt som deles på tvers av flere sider eller rutesegmenter. En layout kan inneholde elementer som headere, footere, sidefelt eller andre komponenter som skal være konsistente gjennom en del av applikasjonen din. Layouter defineres ved hjelp av filen `layout.js` (eller `layout.tsx`).

Layouter er nestet. Dette betyr at rotlayouten (`app/layout.js`) omslutter hele applikasjonen, og nestede layouter omslutter spesifikke rutesegmenter. Når man navigerer mellom ruter som deler en layout, bevarer Next.js layoutens tilstand og unngår å gjengi den på nytt, noe som resulterer i forbedret ytelse og en jevnere brukeropplevelse.

Eksempel:

// app/layout.js

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <header>
          <nav>
            <a href="/">Hjem</a> |
            <a href="/blog">Blogg</a>
          </nav>
        </header>
        <main>{children}</main>
        <footer>
          <p>Copyright 2023</p>
        </footer>
      </body>
    </html>
  );
}

I dette eksempelet definerer `RootLayout` den grunnleggende HTML-strukturen, headeren, footeren og navigasjonen for hele applikasjonen. Enhver side som gjengis i `app`-mappen vil bli omsluttet av denne layouten.

4. Maler: Bevare tilstand mellom ruter

I likhet med layouter, omslutter maler også barnruter. Men i motsetning til layouter, oppretter maler en ny komponentinstans for hver barnrute. Dette betyr at malens tilstand ikke bevares når man navigerer mellom ruter innenfor malen. Maler er nyttige for scenarioer der du trenger å nullstille eller re-initialisere tilstand ved ruteoverganger. Bruk template.js (eller template.tsx) for å lage maler.

5. Rutegrupper: Organisere ruter uten URL-segmenter

Rutegrupper lar deg organisere rutene dine i App Directory uten å påvirke URL-strukturen. Rutegrupper defineres ved å pakke mappenavn i parenteser, f.eks. `(group-name)`. Disse parentesene forteller Next.js å behandle mappen som en logisk grupperingsmekanisme i stedet for et rutesegment.

Dette er spesielt nyttig for å organisere store applikasjoner med mange ruter. For eksempel kan du bruke rutegrupper til å skille forskjellige deler av applikasjonen din, som `(marketing)` og `(app)`. Disse gruppene påvirker kun filstrukturen, ikke URL-stiene.

Eksempel:

app/
  (marketing)/
    home/
      page.js  // Tilgjengelig på /home
    about/
      page.js  // Tilgjengelig på /about
  (app)/
    dashboard/
      page.js  // Tilgjengelig på /dashboard

6. Dynamiske ruter: Håndtering av variable segmenter

Dynamiske ruter lar deg lage ruter med variable segmenter. Dette er nyttig for scenarioer der du trenger å generere ruter basert på data, som blogginnlegg, produktsider eller brukerprofiler. Dynamiske rutesegmenter defineres ved å omslutte segmentnavnet i hakeparenteser, f.eks. `[id]`. `id`-en representerer en parameter som kan nås inne i `page.js`-komponenten.

Eksempel:

app/
  blog/
    [slug]/
      page.js

I dette eksempelet er `[slug]` et dynamisk rutesegment. En URL som `/blog/mitt-forste-innlegg` vil matche denne ruten, og `slug`-parameteren vil bli satt til `mitt-forste-innlegg`. Du kan få tilgang til `slug`-parameteren i `page.js`-komponenten ved å bruke `params`-propen.

// app/blog/[slug]/page.js

export default function BlogPost({ params }) {
  const { slug } = params;
  return (
    <div>
      <h1>Blogginnlegg: {slug}</h1>
      <p>Innholdet i blogginnlegget med slug: {slug}</p>
    </div>
  );
}

Du må generere de mulige verdiene for disse dynamiske rutene. Next.js tilbyr `generateStaticParams`-funksjonen for statisk sidegenerering (SSG) og server-side rendering (SSR). Denne funksjonen lar deg spesifisere hvilke dynamiske ruter som skal forhåndsrendres ved byggetid.

// app/blog/[slug]/page.js

export async function generateStaticParams() {
  const posts = [
    { slug: 'mitt-forste-innlegg' },
    { slug: 'mitt-andre-innlegg' },
  ];

  return posts.map((post) => ({ slug: post.slug }));
}

export default function BlogPost({ params }) {
  const { slug } = params;
  return (
    <div>
      <h1>Blogginnlegg: {slug}</h1>
      <p>Innholdet i blogginnlegget med slug: {slug}</p>
    </div>
  );
}

7. Catch-all-segmenter: Håndtering av ukjente ruter

Catch-all-segmenter er en type dynamisk rute som lar deg matche et hvilket som helst antall segmenter i en URL. De defineres ved å sette tre prikker foran segmentnavnet, f.eks. `[...path]`. Catch-all-segmenter er nyttige for å lage fleksible ruter som kan håndtere en rekke URL-strukturer.

Eksempel:

app/
  docs/
    [...path]/
      page.js

I dette eksempelet er `[...path]` et catch-all-segment. URL-er som `/docs/introduction`, `/docs/api/reference` og `/docs/examples/basic` vil alle matche denne ruten. `path`-parameteren vil være en matrise som inneholder de matchede segmentene.

// app/docs/[...path]/page.js

export default function DocsPage({ params }) {
  const { path } = params;
  return (
    <div>
      <h1>Dokumentasjon</h1>
      <p>Sti: {path.join('/')}</p>
    </div>
  );
}

8. Parallelle ruter: Gjengi flere sider samtidig

Parallelle ruter lar deg gjengi flere sider innenfor samme layout samtidig. Dette er spesielt nyttig for å lage komplekse UI-mønstre, som dashbord med flere paneler eller modale dialogbokser som vises oppå den nåværende siden. Parallelle ruter defineres ved hjelp av @-symbolet, f.eks. `@children`, `@modal`. De kan spesifiseres direkte i URL-en eller navigeres til ved hjelp av `useRouter`-kroken.

Eksempel:

app/
  @children/
    page.js // Gjengir hovedinnholdet
  @modal/
    login/
      page.js // Gjengir innloggingsmodalen

For å vise parallelle ruter, bruk ``-komponenten.

9. Avskjærende ruter: Skape sofistikerte UI-overganger

Avskjærende ruter (Intercepting Routes) lar deg laste en rute fra en annen del av applikasjonen din innenfor konteksten av den nåværende ruten. Dette kan brukes til å lage sofistikerte UI-overganger, som å vise en modal dialogboks når du klikker på en lenke uten å navigere bort fra den nåværende siden. De defineres ved hjelp av (...)-syntaksen.

Datahenting i App Directory

App Directory introduserer nye og forbedrede måter å hente data på, ved å utnytte React Server Components og `fetch`-API-et med innebygde caching- og revalideringsmuligheter. Dette fører til bedre ytelse og en mer strømlinjeformet utviklingsopplevelse. Både server- og klientkomponenter kan hente data, men strategien er forskjellig.

1. Datahenting i serverkomponenter

Serverkomponenter, som er standard i App Directory, kan hente data direkte fra databaser eller API-er. Dette gjøres i komponentfunksjonen før gjengivelse. Siden serverkomponenter kjøres på serveren, kan du trygt inkludere hemmelige nøkler og legitimasjon uten å eksponere dem for klienten. `fetch`-API-et blir automatisk memoisert, noe som betyr at identiske dataforespørsler blir deduplisert, noe som ytterligere forbedrer ytelsen.

// app/page.js

async function getData() {
  const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  // Returverdien blir *ikke* serialisert
  // Du kan returnere Date, Map, Set, osv.

  if (!res.ok) {
    // Dette vil aktivere den nærmeste `error.js` Error Boundary
    throw new Error('Klarte ikke å hente data');
  }

  return res.json();
}

export default async function Page() {
  const data = await getData();

  return <div>{data.title}</div>;
}

2. Datahenting i klientkomponenter

Klientkomponenter, markert med `'use client'`-direktivet øverst i filen, kjøres i brukerens nettleser. Datahenting i klientkomponenter innebærer vanligvis bruk av `useEffect`-kroken og et bibliotek som `axios` eller `fetch`-API-et. Server Actions gir en trygg måte å mutere serverdata fra klientkomponenter. Dette gir en sikker måte for klientkomponenter å samhandle med data på serveren uten å eksponere API-endepunkter direkte.

// app/components/ClientComponent.js
'use client';

import { useState, useEffect } from 'react';

export default function ClientComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    async function fetchData() {
      const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
      const data = await res.json();
      setData(data);
    }

    fetchData();
  }, []);

  if (!data) {
    return <div>Laster...</div>;
  }

  return <div>{data.title}</div>;
}

SEO-hensyn med App Directory

App Directorys server-først-tilnærming gir betydelige fordeler for SEO. Siden innholdet gjengis på serveren, kan søkemotor-crawlere enkelt få tilgang til og indeksere sideinnholdet. Her er noen viktige SEO-hensyn:

Fordeler med å bruke App Directorys rutingsystem

App Directorys rutingsystem tilbyr en rekke fordeler som forbedrer utviklingsprosessen, applikasjonsytelsen og bidrar til en bedre brukeropplevelse. La oss se nærmere på disse fordelene:

Praktiske eksempler på App Directory-ruting i aksjon

For å illustrere kraften og fleksibiliteten i App Directorys rutingsystem, la oss se på noen praktiske eksempler:

1. Bygge en enkel blogg med dynamiske ruter

Tenk deg en bloggapplikasjon der hvert blogginnlegg har sin egen unike URL basert på sin slug. Med App Directory kan dette enkelt implementeres ved hjelp av dynamiske ruter:

``` app/ blog/ [slug]/ page.js ```

`[slug]`-mappen representerer et dynamisk rutesegment, som vil matche enhver URL under `/blog/`-stien. `page.js`-filen i `[slug]`-mappen vil gjengi innholdet for det tilsvarende blogginnlegget.

```javascript // app/blog/[slug]/page.js export async function generateStaticParams() { // Hent alle blogginnlegg fra databasen eller API-et const posts = await fetchPosts(); // Map innleggene til en matrise av slug-parametere return posts.map((post) => ({ slug: post.slug })); } export default async function BlogPost({ params }) { const { slug } = params; // Hent blogginnlegget med den matchende slug-en const post = await fetchPost(slug); if (!post) { return <div>Innlegg ikke funnet</div>; } return ( <article> <h1>{post.title}</h1> <p>{post.content}</p> </article> ); } ```

Dette eksempelet demonstrerer hvordan man bruker dynamiske ruter til å lage individuelle sider for hvert blogginnlegg på en enkel og effektiv måte.

2. Implementere en modal dialogboks med avskjærende ruter

Anta at du vil implementere en modal dialogboks som vises når en bruker klikker på en lenke, uten å navigere bort fra den nåværende siden. Dette kan oppnås ved hjelp av avskjærende ruter:

``` app/ (.)photos/ [id]/ @modal/ page.js page.js ```

Her avskjærer `(.)photos/[id]/@modal/page.js` forespørsler som går til `photos/[id]` fra den nåværende siden. Når en bruker klikker på en lenke til et spesifikt bilde, vil modal dialogboksen vises oppå den nåværende siden, i stedet for å navigere til en ny side.

3. Lage en dashbordlayout med parallelle ruter

Se for deg at du bygger en dashbordapplikasjon med flere paneler som må gjengis samtidig. Parallelle ruter kan brukes for å oppnå denne layouten:

``` app/ @analytics/ page.js // Analyse-dashbord @settings/ page.js // Innstillingspanel page.js // Hoved-dashbordlayout ```

I denne strukturen representerer `@analytics` og `@settings` parallelle ruter som vil bli gjengitt innenfor hoved-dashbordlayouten. Hver parallelle rute har sin egen page.js-fil som definerer innholdet for det panelet. Layouten kan bestemme hvor disse skal plasseres ved hjelp av <Slot>-komponenten.

Migrering fra Pages Directory til App Directory

Å migrere en eksisterende Next.js-applikasjon fra Pages Directory til App Directory krever nøye planlegging og utførelse. Selv om App Directory tilbyr betydelige fordeler, introduserer den også nye konsepter og mønstre som utviklere må forstå. Her er en trinnvis guide for å hjelpe deg gjennom migreringsprosessen:

  1. Forstå nøkkelforskjellene: Før du begynner migreringen, sørg for at du grundig forstår de viktigste forskjellene mellom Pages Directory og App Directory, inkludert rutingsystemet, datahenting og komponentarkitektur.
  2. Opprett en `app`-mappe: Opprett en ny mappe med navnet `app` i roten av Next.js-prosjektet ditt. Denne mappen vil huse alle komponentene og rutene som er en del av App Directory.
  3. Migrer ruter gradvis: Begynn med å migrere ruter inkrementelt, én om gangen. Dette vil tillate deg å teste og feilsøke hver rute individuelt, og minimere risikoen for å introdusere feil.
  4. Konverter komponenter til serverkomponenter: Konverter dine eksisterende React-komponenter til serverkomponenter når det er mulig. Dette vil forbedre ytelsen og redusere mengden JavaScript som må lastes ned og kjøres i nettleseren.
  5. Oppdater datahentingslogikken: Oppdater datahentingslogikken din for å dra nytte av App Directorys innebygde datahentingsmuligheter. Dette kan innebære å flytte datahentingskode fra klientkomponenter til serverkomponenter.
  6. Implementer layouter og maler: Implementer layouter og maler for å definere delte UI-elementer som er konsistente på tvers av flere sider.
  7. Test grundig: Test hver migrerte rute grundig for å sikre at den fungerer korrekt og at det ikke er noen regresjoner.
  8. Fjern `pages`-mappen: Når alle rutene er migrert, kan du fjerne `/pages`-mappen.

Konklusjon

Next.js App Directory representerer en betydelig utvikling innen filbasert ruting, og tilbyr utviklere en mer organisert, ytelsessterk og fleksibel måte å bygge moderne webapplikasjoner på. Ved å forstå nøkkelkonseptene og omfavne de nye funksjonene, kan utviklere utnytte App Directory til å skape eksepsjonelle brukeropplevelser og oppnå større produktivitet. Fremtiden for Next.js-utvikling ligger i App Directory, og å ta den i bruk er et strategisk trekk for å bygge banebrytende webapplikasjoner. Det er et kraftig verktøy for utviklere over hele verden.

Ettersom Next.js-økosystemet fortsetter å utvikle seg, er App Directory posisjonert til å bli standarden for å bygge robuste, skalerbare og ytelsessterke webapplikasjoner. Omfavn endringen, utforsk mulighetene, og lås opp det fulle potensialet til Next.js!