Tilbake

Stier og mappestruktur

Av Sondre Slåttedal HavellenPublisert 14/6-22

I NextJs er det mappestrukturen som hovedsaklig bestemmer stiene til siden din. Filer man legger under en spesiell mappe som heter pages vil styre hva slags sider en bruker kan besøke. Et eksempel på mappestruktur kan se slik ut:

1pages
2| index.tsx
3| about.tsx
4 - content
5   | index.tsx
6   | page.tsx

Her finner vi altså fire distinkte stier - “/”, “/about”, “/content” og “/content/page”. Videre har man også en spesialisert mappe under pages som heter “api”. Her finner en API-stier, og det kan du lese mer om i artikkelen “API-routes”.

Det er også to reserverte filnavn under pages som heter _app.tsx og _document.tsx. _app.tsx brukes hovedsaklig til å initialisere siden. Videre kan en

  • persistere layout mellom sideendringer
  • beholder tilstand mellom sideendringer
  • endre standard feilhåndtering
  • injisere ytterlig data på sider
  • legge til global css

_document.tsx brukes til å endre <html> og <body> på en side. Dette er nødvendig fordi en kan ikke endre dette på standard sider under pages.

En kan også overstyre 404-sider og 500-sider (og sikkert flere) ved å opprette sider kalt 404.tsxog 500.tsxunder pages.

Dynamiske stier

En annen viktig funksjon i NextJs er dynamiske stier. For en gitt applikasjon kan en ikke alltid forvente å vite det fulle settet med sider. For eksempel kan en ecommerce-side ha forskjellige produktsider styrt av en database. Da trenger man dynamiske stier for å kunne håndtere dette. Dynamiske sider kommer i tre varianter:

  • [id].tsx - enkel dynamisk side
  • […path].tsx - nøstet dynamisk side (eller “Catch all routes”)
  • [[…path]].tsx - samme som over men fanger index og

I tillegg til getStaticProps krever dynamiske sider en funksjon som heter getStaticPaths. Denne brukes for å hente ut alle de dynamiske sidene for pre-rendring. For eksempel kan en ha lagret 1000 produkter i en database. Da kan en hente produkt-nøkler fra databasen og sende de vider til NextJs slik at NextJs kan statiskgenerere disse sidene. Et eksempel på boilerplate kan se slik ut (for en side kalt [id].tsx):

1import {GetStaticPathsContext, GetStaticPathsResult, GetStaticPropsContext, GetStaticPropsResult} from "next";
2
3export const getStaticPaths = async (context: GetStaticPathsContext): Promise<GetStaticPathsResult<{ id: string }>> => {
4
5  const ids = await fetchAllProductIds();
6
7  return {
8    paths: ids.map(id => ({
9      params: {
10        id
11      }
12    })),
13    fallback: false
14  }
15};
16
17export const getStaticProps = async (context: GetStaticPropsContext<{ id: string }>): Promise<GetStaticPropsResult<{ productData: any }>> => {
18
19  const id = context.params?.id;
20  if(!id) return { notFound: true };
21
22  const productData = fetchProductData(id);
23  if(!productData) return { notFound: true }
24
25  return {
26    props: {
27      productData
28    },
29    revalidate: 60
30  }
31
32};
33
34export default function ProductPage(props: any) {
35  return <pre>
36    {JSON.stringify(props, undefined, 4)}
37  </pre>
38}

Her henter vi altså et sett med produkt-nøkler og pre-genererer siden for alle disse nøklene.

Catch-all-sider er noe mer involvert og benytter seg ofte av to-dimensjonale lister - typisk en liste av spesifikke sider hvor hver subliste inneholder sti-komponentene. For eksempel ([…path].tsx) - /foo/bar og blir til [ { params: { path: [“foo”, “bar”] } }, { params: { path: [“foo”, “baz”] } } ]. Du finner et komplett eksempel i kildekoden til denne siden her.

Les mer

Du finner mer informasjon på NextJs sin dokumentasjonsside