Hoe werkt routing?
In Next.js maak je geen routes in code (zoals React Router). Je maakt gewoon mappen en bestanden aan. De mappenstructuur = de URL structuur.
app/
├── page.js → /
├── workouts/
│ ├── page.js → /workouts
│ └── [id]/
│ └── page.js → /workouts/42
💡 Analoog aan Express routes
In Express schreef je: app.get('/workouts', handler)
In Next.js maak je gewoon de map app/workouts/page.js aan. Geen code nodig!
Stap 1 — Maak de overzichtspagina aan
Maak een nieuwe map workouts aan in app/ en maak daarin een nieuw bestand page.js:
app/
└── workouts/
└── page.js ← nieuw bestand aanmaken
Zet deze code in app/workouts/page.js:
// app/workouts/page.js
// Tijdelijke data (later vervangen door echte API)
const workouts = [
{ id: 1, title: 'Push Day', reps: 10, load: 50 },
{ id: 2, title: 'Pull Day', reps: 8, load: 60 },
{ id: 3, title: 'Leg Day', reps: 12, load: 80 },
];
export default function WorkoutsPage() {
return (
<main>
<h1>Mijn Workouts</h1>
<ul>
{workouts.map((workout) => (
<li key={workout.id}>
<strong>{workout.title}</strong> — {workout.reps} reps @ {workout.load}kg
</li>
))}
</ul>
</main>
);
}
✅ Test het
Ga naar http://localhost:3000/workouts — je ziet de drie workouts!
Stap 3 — Maak de detailpagina aan
💡 Wat is een dynamische route?
Voor een detailpagina per workout heb je een route nodig die een variabele ID accepteert. In Next.js doe je dat door een map met blokhaken aan te maken: [id]. Vergelijk met Express: router.get('/workouts/:id', ...) — werkt hetzelfde.
3a — Maak de map en het bestand aan
app/
└── workouts/
├── page.js
└── [id]/
└── page.js ← nieuw bestand aanmaken
Zet deze code in app/workouts/[id]/page.js:
// app/workouts/[id]/page.js
// Tijdelijke data (later van API)
const workouts = [
{ id: 1, title: 'Push Day', reps: 10, load: 50 },
{ id: 2, title: 'Pull Day', reps: 8, load: 60 },
{ id: 3, title: 'Leg Day', reps: 12, load: 80 },
];
export default async function WorkoutDetailPage({ params }) {
const { id } = await params;
const workout = workouts.find((w) => w.id === Number(id));
if (!workout) {
return <p>Workout niet gevonden.</p>;
}
return (
<div>
<h1>{workout.title}</h1>
<p>Reps: {workout.reps}</p>
<p>Load: {workout.load}kg</p>
</div>
);
}
3b — Voeg links toe in de overzichtspagina
Update app/workouts/page.js zodat elke workout klikbaar is:
// app/workouts/page.js
import Link from 'next/link';
const workouts = [
{ id: 1, title: 'Push Day', reps: 10, load: 50 },
{ id: 2, title: 'Pull Day', reps: 8, load: 60 },
{ id: 3, title: 'Leg Day', reps: 12, load: 80 },
];
export default function WorkoutsPage() {
return (
<main>
<h1>Mijn Workouts</h1>
<ul>
{workouts.map((workout) => (
<li key={workout.id}>
<Link href={`/workouts/${workout.id}`}>
{workout.title} — {workout.reps} reps @ {workout.load}kg
</Link>
</li>
))}
</ul>
</main>
);
}
✅ Test het
Ga naar /workouts en klik op een workout. Je komt op de detailpagina van dat specifieke workout!
Problemen oplossen
❌ Pagina geeft 404
Oorzaak: page.js mist of map heeft verkeerde naam
Check: Heeft de map een page.js bestand? Is de mapnaam exact gelijk aan de URL?
❌ params.id is undefined
Oorzaak: Map heet niet [id] of je gebruikt de verkeerde naam
Check: Map moet exact [id] heten (met blokhaken). In de component gebruik je dan params.id.
❌ Link werkt niet / pagina herlaadt volledig
Oorzaak: Je gebruikt <a href="..."> in plaats van <Link href="...">
Oplossing: Vervang <a> door Link en importeer bovenaan: import Link from 'next/link'
Checklist
✅ Check of je hebt:
app/workouts/page.jsaangemaakt- Lijst met workouts zichtbaar op
/workouts - Navigatie in
layout.jsmetLinkcomponenten app/workouts/[id]/page.jsaangemaakt- Detailpagina werkt via klikken op een workout
Volgende Stap
Routing werkt! Nu leren we het verschil tussen Server en Client Components.
Het belangrijkste concept in Next.js App Router