Wat is Next.js?

Het Next.js woord logo waarbij de letter N vast zit aan de letter E, en de letter X half doorgesneden is. Het '.js' gedeelte is in een kleiner lettertype, ik vermoed om aan te duiden dat het wat minder belangrijk is.

Next.js is een zogenaamd: React meta framework. Een meta framework is een framework dat om een ander framework / library wrapped. Het breidt daarmee als het ware React uit, en geeft het een aantal extra features.

React noemt zichzelf altijd trots een library in plaats van een framework (dit valt echter te betwisten) hierdoor heeft React een aantal belangrijke features niet zoals:

  • Een Router, om URLs aan componenten te koppelen

  • Een build mechanisme: het next build commando output een kant en klaar te serveren folder uit, next dev start een dev server.

  • Een deployment mechanisme: upload het eenvoudig naar Vercel, met alle kosten van dien.

  • Een manier om React server side te runnen via React server components.

Het zijn deze missende features die Next.js opvult!

De Next.js app Router

Een router heeft als doel om een URL aan een React component te koppelen. Next.js doet dit via een file based (bestandgebaseerde) router.

Binnen Next.js betwekent dit heel simpel: je hebt ergens een folder genaamd app, in deze folder staan al je web pagina's.

Maak je binnen de app folder bijvoorbeeld het bestand: /over/page.tsx aan, dan maak je een "/over" pagina.

Je kan ook dynamische routes maken door [] te gebruiken in de folder naam: /pokemon/[id]/page.tsx. Dit matched dan op /pokemon/1 en op /pokemon/2, maar ook op /pokemon/noot

Elk page.tsx bestand dient een default export te hebben, deze moet een React Component zijn. Next.js rendered dan dit component als de content van de pagina. Bijvoorbeeld:

export default function WatIsNextJsPage() {
  return (
    <Page title="Wat is Next.js?">
      <Section>
        <H1>Wat is Next.js?</H1>

Next.js heeft ook ondersteuning voor error routes, 404 / not found routes, herbruikbare layouts en nog veel meer andere features.

De router in Next.js is al met al zeer uitgebreid. En in mijn ogen het beste onderdeel van Next.js.

React Server Components (RSC)

Next.js maakt het mogelijk om delen van je applicatie server side te renderen. Wanneer iets server side gerendered wordt bedoelen we dat er complete HTML over de lijn wordt gestuurd.

Dit is goed voor Search Engine Optimalization (SEO) want die gaan beter om met HTML dan JavaScript gegenereerde websites. Het indexeren zelf gaat beter, en het performt ook vaak nog sneller. Plus wanneer de gebruiker geen JavaScript heeft dan zien ze nog steeds een pagina.

Een RSC leeft dus op de "server", en geeft hem een superkracht: het is mogelijk om de function als async te markeren, en zo te wachten met renderen todat je bepaalde data in je handen hebt.

Je kan bijvoorbeeld een query naar de database kunnen sturen:

export default async function PokemonList() {
  const pokemons = await db.query('SELECT * FROM POKEMON');

  return (
    <ul>
      {pokemons.map((pokemon) => (
        <li key={pokemon.id}>{pokemon.name}</li>
      ))}
    </ul>
  );
}

Ik raad niet aan om je database direct in Next.js aan te roepen, maar het demonstreert wel hoe krachtig het idee is.

Client vs Server components

In Next.js heb je twee soorten componenten:

  • Server components: componenten die server side kunnen worden gerenderd.

  • Client components: componenten die éénmalig server side worden gerenderd, en daarna op de client / browser worden gerendered.

Een client component kan zien als een old school / classic / tradioneel component. Dit type component bestaat als sinds jaar en dag.

Een server component is dus nieuwer, en wordt op de server gerenderd. Een server component heeft als output dus eigenlijk rauwe HTML.

Wat Next.js vervolgens kan is deze type soorten componenten door elkaar laten weven. Een server component kan client components renderen. Een client component kan server components renderen via de children prop.

Een server component is geschikt voor statische onderdelen van een pagina, dus de onderdelen die niet veranderen en geen gebruikers interactie hebben. Een client component support user interactie heb je een useState nodig, of onClick event listeners, dan moet je een client component gebruiken.

Wanneer boven in een jsx / tsx file "use client" zet markeer je een component als een client component. Alle onderliggende componenten / imports worden dan automatisch in de client boundary gezet. Een client boundary is de grens tussen client en server.

Hier onder zie je een interactief voorbeeld:

Statische header van website
Scroll: 0
Statische footer van website
  • Server component.
  • Client component.

Next.js modussen

Je kan Next.js in twee modussen draaien:

  • De export mode: in deze modus maakt Next.js van jouw website een complete statische build. Dit is geschikt voor zowel een website of webapp.

    De output van next build, wat een productie versie oplevert, zal dan alleen bestaan uit statische files. Een statische file is een file die nooit hoeft te veranderen!

    In andere woorden: bij een statische file krijgt elke gebruiker hetzelfde te zien.

    Je hebt dan geen JavaScript runtime nodig zoals Node.js of Bun of Deno om jouw website te serveren. Je kan dan bijvoorbeeld ook een CDN (Content Delivery Network) gebruiken voor je website, of een simpele webserver zoals apache of nginx

    Omdat de content statisch is kan je het geheel ook nog aggresief cachen!

    De export modus is geschikt om websites mee te maken, maar ook om SPAs mee te maken.

    Deze website gebruikt Next.js in de export modus!

  • De normal mode: in deze modus genereert next build waar hij kan zo veel mogelijk statische files. Maar zal voor de onderdelen die dynamische content nodig is dat adhoc / on the fly genereren.

    Wanneer je dan next start runt dan start er een "productie" server op die voor elk request het dynamische deel genereert. Je hebt dan wel een JavaScript runtime nodig zoals bijvoorbeeld Node.js op je server.

    Of je host het bij Vercel het bedrijf achter Next.js. Voor een botergoude, maar meer kostende ervaring!

Het feit dat Next.js HTML over de lijn stuurt maakt Next.js geschikt voor het maken van websites. maar ook geschikt voor het maken van webapps

Waarschuwing: App router vs Pages router

Next.js heeft twee soorten routers de pages router en de app router.

De app router is de modernste van de twee en support React Server Components, en daarmee ook een beter caching verhaal.

De pages router is de oudere / eerste router, en is eigenlijk de legacy router. Maar let op: Next.js is heel terughoudend met het zeggen dat de pages router eigenlijk legacy is!

De app router is de router die alle moderne features krijgt. De pages router krijgt vrijwel alleen bug fixes. Dus gebruik de app router!

Wat vindt Maarten?

Een foto van Maarten, een gemiddeld gezicht al zeg ik het zelf.

Next.js is een prima framework. Vooral de router is ijzersterk en bied een fijne filebased / bestandgebaseerde API aan.

De duistere kant van Next.js vindt ik het pushen naar Vercel als hosting optie. Al kan je het ook prima zelf hosten. Ik heb ook ooit een blogpost geschreven over mijn my gripes with Next.js / Next.js zijn mindere kwaliteiten.

Al met al een hele populaire / veilige optie. Weet je echter van tevoren dat je alleen een webapplicatie (lees alles achter login) wilt maken is vite misschien een betere optie.

Contact

Neem contact op via e-mail, phone of app, als je vragen hebt of een offerte wilt aanvragen.

Vraag een offerte aan Boek kennismakingsgesprek