Next.js 16 Middleware in 2026: Edge Runtime, Authenticatie en Sollicitatievragen
Uitgebreide handleiding over Next.js 16 Middleware met Edge Runtime, authenticatiepatronen, URL rewriting en veelgestelde technische sollicitatievragen voor frontend-ontwikkelaars.

Next.js 16 Middleware draait voordat elke request de server bereikt, waardoor het de eerste verdedigingslinie vormt voor authenticatie, lokalisatie en request-manipulatie. Het begrijpen van middleware is essentieel voor het bouwen van productie-applicaties en een veelvoorkomend onderwerp in frontend-sollicitatiegesprekken.
Next.js 16 Middleware draait standaard in de Edge Runtime, wat betekent dat het in datacenters dicht bij gebruikers draait met cold starts van minder dan een milliseconde. Dit maakt het ideaal voor authenticatiecontroles en redirects die moeten plaatsvinden voordat de pagina wordt gerenderd.
Hoe Next.js 16 Middleware Onder de Motorkap Werkt
Middleware in Next.js 16 onderschept requests voordat ze de route handler of page component bereiken. Het middleware-bestand moet in de root van het project worden geplaatst (naast app/ of pages/) en exporteert een standaardfunctie die een NextRequest-object ontvangt.
De Edge Runtime-beperking betekent dat middleware geen Node.js API's zoals fs of Buffer kan gebruiken. Het draait op V8 isolates, vergelijkbaar met Cloudflare Workers, wat globale distributie mogelijk maakt maar de beschikbare API's beperkt tot webstandaarden.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Access request headers, cookies, and URL
const token = request.cookies.get('session')?.value
const pathname = request.nextUrl.pathname
// Log for debugging (visible in Vercel logs)
console.log(`Middleware: ${request.method} ${pathname}`)
// Continue to the route handler
return NextResponse.next()
}
// Configure which paths trigger middleware
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}De matcher-configuratie gebruikt een regex-achtige syntax om te definiëren welke paden de middleware activeren. Zonder deze configuratie draait middleware op elke request, inclusief statische assets.
Authenticatiepatronen met Next.js Middleware
Middleware blinkt uit in authenticatie omdat het draait voordat enige paginacode wordt uitgevoerd. Een gebruiker zonder geldige sessie ziet nooit beschermde content, zelfs niet kort. Dit verschilt van client-side authenticatiecontroles die beschermde content kort kunnen laten zien voordat ze doorverwijzen.
Het volgende patroon valideert een sessietoken en leidt niet-geauthenticeerde gebruikers om. Het integreert met elke auth-provider die sessiegegevens opslaat in cookies of headers.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const protectedPaths = ['/dashboard', '/settings', '/profile']
const authPaths = ['/login', '/signup']
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
const sessionToken = request.cookies.get('session')?.value
// Check if path requires authentication
const isProtectedPath = protectedPaths.some(path =>
pathname.startsWith(path)
)
const isAuthPath = authPaths.some(path =>
pathname.startsWith(path)
)
// Validate session token (call auth service)
const isValidSession = sessionToken
? await validateSession(sessionToken)
: false
// Redirect unauthenticated users to login
if (isProtectedPath && !isValidSession) {
const loginUrl = new URL('/login', request.url)
loginUrl.searchParams.set('callbackUrl', pathname)
return NextResponse.redirect(loginUrl)
}
// Redirect authenticated users away from auth pages
if (isAuthPath && isValidSession) {
return NextResponse.redirect(new URL('/dashboard', request.url))
}
return NextResponse.next()
}
async function validateSession(token: string): Promise<boolean> {
// Call auth API endpoint or decode JWT
// Edge-compatible: use fetch, not Node.js crypto
try {
const response = await fetch('https://api.example.com/validate', {
headers: { Authorization: `Bearer ${token}` },
})
return response.ok
} catch {
return false
}
}De callbackUrl-parameter bewaart de oorspronkelijke bestemming, zodat gebruikers na het inloggen op de pagina landen die ze oorspronkelijk hadden opgevraagd.
Path Matching en de Matcher Configuratie
De matcher-configuratie bepaalt welke requests de middleware activeren. Fouten hier leiden tot prestatieproblemen (middleware die draait op elke statische asset) of beveiligingslekken (beschermde paden die geen auth-controles activeren).
Next.js 16 ondersteunt drie matcher-syntaxen: string-paden, padpatronen met parameters en regex-achtige patronen met negatieve lookaheads.
// Option 1: Simple string paths
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*'],
}
// Option 2: Exclude static assets with negative lookahead
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico|public/).*)'],
}
// Option 3: Conditional matching with has/missing
export const config = {
matcher: [
{
source: '/api/:path*',
has: [{ type: 'header', key: 'Authorization' }],
},
{
source: '/dashboard/:path*',
missing: [{ type: 'cookie', key: 'session' }],
},
],
}De has- en missing-condities in optie 3 voegen logica toe voordat de middleware zelfs wordt uitgevoerd. Dit is efficiënter dan controleren binnen de middleware-functie.
Klaar om je React / Next.js gesprekken te halen?
Oefen met onze interactieve simulatoren, flashcards en technische tests.
Request- en Response-Manipulatie in Middleware
Naast authenticatie kan middleware requests modificeren voordat ze route handlers bereiken en responses voordat ze de client bereiken. Veelvoorkomende use cases zijn het toevoegen van security headers, URL rewriting voor A/B-tests en het injecteren van geolocatiegegevens.
De NextResponse-klasse biedt methodes voor elk type modificatie. Rewrites veranderen de bestemming zonder de browser-URL te wijzigen, terwijl redirects beide bijwerken.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const response = NextResponse.next()
// Add security headers to all responses
response.headers.set('X-Frame-Options', 'DENY')
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set(
'Referrer-Policy',
'strict-origin-when-cross-origin'
)
// Inject geolocation into request headers for route handlers
const geo = request.geo
if (geo?.country) {
response.headers.set('x-user-country', geo.country)
response.headers.set('x-user-city', geo.city ?? 'unknown')
}
return response
}Geolocatiegegevens (request.geo) worden ingevuld door Vercel's Edge Network. Self-hosted deployments moeten dit configureren via de hosting-provider of een externe IP-geolocatiedienst gebruiken.
URL Rewriting voor A/B Tests en Feature Flags
Middleware rewrites maken het mogelijk om verschillende pagina's te serveren op basis van cookies, headers of willekeurige toewijzing zonder dat de client het weet. Dit patroon drijft A/B-testframeworks en geleidelijke feature-rollouts aan.
De rewrite vindt plaats op de edge, dus beide varianten hebben dezelfde URL en profiteren waar gepast van edge caching.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
// Check for existing variant assignment
let variant = request.cookies.get('ab-variant')?.value
// Assign variant if not set (50/50 split)
if (!variant && pathname === '/pricing') {
variant = Math.random() < 0.5 ? 'control' : 'treatment'
const response = NextResponse.rewrite(
new URL(`/pricing/${variant}`, request.url)
)
response.cookies.set('ab-variant', variant, {
maxAge: 60 * 60 * 24 * 30, // 30 days
httpOnly: true,
})
return response
}
// Rewrite to assigned variant
if (variant && pathname === '/pricing') {
return NextResponse.rewrite(
new URL(`/pricing/${variant}`, request.url)
)
}
return NextResponse.next()
}De cookie bewaart de varianttoewijzing, zodat gebruikers bij terugkerende bezoeken dezelfde versie zien. De 30-daagse vervaldatum balanceert experimentconsistentie met de mogelijkheid om gebruikers aan nieuwe experimenten toe te wijzen.
Edge Runtime Beperkingen en Workarounds
De Edge Runtime ruilt Node.js-compatibiliteit in voor globale distributie en snelle cold starts. Middleware kan geen Node.js-specifieke modules importeren, wat invloed heeft op bibliotheken zoals bcrypt, jsonwebtoken (bij gebruik van RS256) en databaseclients die afhankelijk zijn van TCP-sockets.
De Next.js Edge Runtime-documentatie somt ondersteunde API's op. Web Crypto, fetch en de meeste Web Platform API's werken. Zware berekeningen moeten worden verplaatst naar API-routes die in Node.js draaien.
import { jwtVerify } from 'jose' // Edge-compatible JWT library
import type { NextRequest } from 'next/server'
const JWT_SECRET = new TextEncoder().encode(process.env.JWT_SECRET!)
export async function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value
if (!token) {
return redirectToLogin(request)
}
try {
// jose library works in Edge Runtime
const { payload } = await jwtVerify(token, JWT_SECRET)
// Token is valid, check expiration
if (payload.exp && payload.exp < Date.now() / 1000) {
return redirectToLogin(request)
}
return NextResponse.next()
} catch {
// Invalid token signature or format
return redirectToLogin(request)
}
}
function redirectToLogin(request: NextRequest) {
const url = new URL('/login', request.url)
url.searchParams.set('callbackUrl', request.nextUrl.pathname)
return NextResponse.redirect(url)
}De jose-bibliotheek biedt Edge-compatibele JWT-operaties. Het gebruikt Web Crypto onder de motorkap en vermijdt de Node.js crypto-module.
Veelgestelde Next.js Middleware Sollicitatievragen
Interviewers vragen naar middleware om begrip van de request-lifecycle, beveiligingspatronen en Edge computing-beperkingen te beoordelen. Deze vragen komen voor in senior frontend- en fullstack-rollen die werken met Next.js.
Waar draait middleware in de request-lifecycle?
Middleware draait nadat de request de Next.js-server bereikt maar voordat er route matching of page rendering plaatsvindt. Op Vercel draait het op de Edge, wat het dichtstbijzijnde datacenter bij de gebruiker betekent. Deze plaatsing maakt het ideaal voor authenticatie en redirects omdat ongeldige requests nooit de origin-server bereiken.
Wat kan middleware niet doen vergeleken met API-routes?
Middleware draait in de Edge Runtime, niet Node.js. Het kan geen ingebouwde Node.js-modules gebruiken (fs, path, crypto met bepaalde algoritmes), TCP-gebaseerde databaseclients of npm-packages die afhankelijk zijn van Node.js API's. Zware berekeningen moeten plaatsvinden in API-routes of Server Components.
Hoe wordt authenticatie in middleware afgehandeld zonder te blokkeren?
Het patroon omvat het controleren op een sessiecookie, het valideren tegen een auth-endpoint of door een JWT-handtekening te verifiëren, en doorverwijzen als ongeldig. Om te voorkomen dat elke request wordt geblokkeerd, gebruikt men de matcher-configuratie om middleware alleen op beschermde paden uit te voeren. Stateless JWT-validatie is sneller dan het aanroepen van een externe auth-service bij elke request.
Wat gebeurt er als middleware een fout gooit?
Een onafgehandelde fout in middleware retourneert een 500-response naar de client. De pagina wordt nooit gerenderd. Het wrappen van middleware-logica in try-catch en het retourneren van een fallback-response (vaak NextResponse.next()) voorkomt complete request-failures. Het loggen van de fout voordat wordt doorgegaan helpt bij debugging.
Voor diepgaandere oefening met deze concepten behandelt de Next.js Middleware en Auth sollicitatievragen-module aanvullende scenario's.
Debugging van Middleware in Ontwikkeling en Productie
Middleware-bugs zijn lastig omdat de code op de edge draait, niet in de browser DevTools. Development mode toont middleware-logs in de terminal, maar productie vereist goede logging-infrastructuur.
De volgende aanpak logt middleware-uitvoering met voldoende context om problemen te debuggen zonder gevoelige gegevens bloot te stellen.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const start = Date.now()
const requestId = crypto.randomUUID()
// Log request start
console.log(JSON.stringify({
type: 'middleware_request',
requestId,
method: request.method,
path: request.nextUrl.pathname,
userAgent: request.headers.get('user-agent')?.slice(0, 100),
country: request.geo?.country,
}))
// Process request
const response = processRequest(request)
// Log completion
console.log(JSON.stringify({
type: 'middleware_response',
requestId,
duration: Date.now() - start,
status: response.status,
}))
// Pass request ID to route handlers
response.headers.set('x-request-id', requestId)
return response
}
function processRequest(request: NextRequest): NextResponse {
// Middleware logic here
return NextResponse.next()
}Op Vercel verschijnen deze logs in het Functions-tabblad. Self-hosted deployments moeten logs naar een service zoals Datadog sturen of gestructureerde logging gebruiken die het hostingplatform kan verwerken.
Middleware Performance Best Practices
Middleware draait op elke gematchte request. Een trage middleware-functie voegt latentie toe aan elke paginalading. Het doel is om middleware-uitvoering voor de meeste requests in minder dan 5ms te voltooien.
- Minimaliseer async-operaties: Elke
awaitvoegt latentie toe. Cache validatieresultaten waar mogelijk. - Gebruik matcher-config: Sluit statische assets en publieke paden uit die geen middleware-logica nodig hebben.
- Vermijd externe calls bij elke request: Valideer JWT's lokaal in plaats van een auth-service aan te roepen. Cache resultaten in cookies waar gepast.
- Houd de bundle klein: Middleware heeft zijn eigen bundle size-limiet (1MB op Vercel). Importeer alleen wat nodig is.
De React Next.js-technologiepagina op /technologies/react-next behandelt gerelateerde concepten zoals Server Components en data-fetching patronen die middleware-kennis aanvullen.
Begin met oefenen!
Test je kennis met onze gespreksimulatoren en technische tests.
Next.js 16 Middleware Checklist voor Productie
- Plaats middleware in de project-root als
middleware.ts, niet binnenapp/ofpages/ - Configureer de
matcherom_next/static,_next/imageen publieke assets uit te sluiten van middleware-uitvoering - Gebruik Edge-compatibele bibliotheken voor JWT-validatie, zoals
josein plaats vanjsonwebtoken - Sla callback-URL's op in query-parameters bij doorverwijzing naar login, zodat gebruikers terugkeren naar hun beoogde bestemming
- Voeg security headers toe in middleware voor consistente toepassing over alle routes
- Log middleware-uitvoering met request ID's om requests door het systeem te traceren
- Houd externe API-calls tot een minimum door tokens lokaal te valideren en gebruikersgegevens te cachen in gesigneerde cookies
Zie jij de bug in React / Next.js?
Een echt codefragment, een verborgen bug, één poging per dag. Zonder account uit te proberen.

Geschreven door
Anthony Fillion-MailletOprichter van SharpSkill
Al meer dan 10 jaar fullstack-ontwikkelaar. Hij leidt SharpSkill en staat in voor alles wat hier verschijnt.
Bijgewerkt op 20 september 2026
Tags
Delen
Gerelateerde artikelen

Next.js 16 Cache Components in 2026: use cache, PPR en Interviewvragen
Next.js 16 Cache Components uitgelegd: use cache directive, PPR, cacheLife, cacheTag, 16.3 Instant Navigations en senior interviewvragen.

Zustand Sollicitatievragen 2026: React State Management en Best Practices
Complete verzameling Zustand sollicitatievragen voor React-ontwikkelaars. Store-patronen, middleware-configuratie, TypeScript-integratie en vergelijking met Context API.

React 19 Suspense en Concurrent Rendering: Streaming SSR en Sollicitatievragen 2026
Uitgebreide handleiding over React 19 Suspense, Concurrent Rendering en Streaming SSR. Inclusief praktische codevoorbeelden en veelgestelde sollicitatievragen voor 2026.