Nederlands

Ontdek Next.js middleware, een krachtige functie voor het onderscheppen en aanpassen van inkomende verzoeken. Leer met praktische voorbeelden hoe u authenticatie, autorisatie, omleiding en A/B-testen implementeert.

Next.js Middleware: Verzoekonderschepping Meesteren voor Dynamische Applicaties

Next.js middleware biedt een flexibele en krachtige manier om inkomende verzoeken te onderscheppen en aan te passen voordat ze uw routes bereiken. Deze mogelijkheid stelt u in staat om een breed scala aan functionaliteiten te implementeren, van authenticatie en autorisatie tot omleiding en A/B-testen, terwijl de prestaties worden geoptimaliseerd. Deze uitgebreide gids leidt u door de kernconcepten van Next.js middleware en laat zien hoe u deze effectief kunt benutten.

Wat is Next.js Middleware?

Middleware in Next.js is een functie die wordt uitgevoerd voordat een verzoek wordt voltooid. Het stelt u in staat om:

Middleware-functies worden gedefinieerd in het middleware.ts (of middleware.js) bestand in de root van uw project. Ze worden uitgevoerd voor elke route binnen uw applicatie, of voor specifieke routes op basis van configureerbare matchers.

Kernconcepten en Voordelen

Request Object

Het request-object geeft toegang tot informatie over het inkomende verzoek, waaronder:

Response Object

Middleware-functies retourneren een Response-object om de uitkomst van het verzoek te bepalen. U kunt de volgende responses gebruiken:

Matchers

Matchers stellen u in staat om te specificeren op welke routes uw middleware moet worden toegepast. U kunt matchers definiëren met behulp van reguliere expressies of padpatronen. Dit zorgt ervoor dat uw middleware alleen wordt uitgevoerd wanneer dat nodig is, wat de prestaties verbetert en de overhead vermindert.

Edge Runtime

Next.js middleware draait op de Edge Runtime, een lichtgewicht JavaScript-runtime-omgeving die dicht bij uw gebruikers kan worden geïmplementeerd. Deze nabijheid minimaliseert de latentie en verbetert de algehele prestaties van uw applicatie, vooral voor wereldwijd verspreide gebruikers. De Edge Runtime is beschikbaar op Vercel's Edge Network en andere compatibele platforms. De Edge Runtime heeft enkele beperkingen, met name het gebruik van Node.js API's.

Praktische Voorbeelden: Middleware-functionaliteiten Implementeren

1. Authenticatie

Authenticatie-middleware kan worden gebruikt om routes te beveiligen waarvoor gebruikers moeten zijn ingelogd. Hier is een voorbeeld van hoe u authenticatie kunt implementeren met behulp van cookies:


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth_token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/dashboard/:path*'],
}

Deze middleware controleert op de aanwezigheid van een auth_token-cookie. Als de cookie niet wordt gevonden, wordt de gebruiker omgeleid naar de /login-pagina. De config.matcher specificeert dat deze middleware alleen moet worden uitgevoerd voor routes onder /dashboard.

Wereldwijd Perspectief: Pas de authenticatielogica aan om verschillende authenticatiemethoden (bijv. OAuth, JWT) te ondersteunen en integreer met verschillende identiteitsproviders (bijv. Google, Facebook, Azure AD) om gebruikers uit diverse regio's te bedienen.

2. Autorisatie

Autorisatie-middleware kan worden gebruikt om de toegang tot bronnen te controleren op basis van gebruikersrollen of -rechten. U kunt bijvoorbeeld een beheerdersdashboard hebben waartoe alleen specifieke gebruikers toegang hebben.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 const token = request.cookies.get('auth_token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 // Example: Fetch user roles from an API (replace with your actual logic)
 const userResponse = await fetch('https://api.example.com/userinfo', {
 headers: {
 Authorization: `Bearer ${token}`,
 },
 });
 const userData = await userResponse.json();

 if (userData.role !== 'admin') {
 return NextResponse.redirect(new URL('/unauthorized', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/admin/:path*'],
}

Deze middleware haalt de rol van de gebruiker op en controleert of deze de admin-rol heeft. Zo niet, dan wordt de gebruiker omgeleid naar een /unauthorized-pagina. Dit voorbeeld gebruikt een placeholder API-eindpunt. Vervang https://api.example.com/userinfo door uw daadwerkelijke authenticatieserver-eindpunt.

Wereldwijd Perspectief: Houd rekening met regelgeving voor gegevensprivacy (bijv. AVG, CCPA) bij het verwerken van gebruikersgegevens. Implementeer passende beveiligingsmaatregelen om gevoelige informatie te beschermen en te voldoen aan lokale wetgeving.

3. Omleiding

Omleidingsmiddleware kan worden gebruikt om gebruikers om te leiden op basis van hun locatie, taal of andere criteria. U kunt bijvoorbeeld gebruikers omleiden naar een gelokaliseerde versie van uw website op basis van hun IP-adres.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const country = request.geo?.country || 'US'; // Default to US if geo-location fails

 if (country === 'DE') {
 return NextResponse.redirect(new URL('/de', request.url))
 }

 if (country === 'FR') {
 return NextResponse.redirect(new URL('/fr', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/'],
}

Deze middleware controleert het land van de gebruiker op basis van hun IP-adres en leidt hen om naar de juiste gelokaliseerde versie van de website (/de voor Duitsland, /fr voor Frankrijk). Als de geo-locatie mislukt, wordt standaard de Amerikaanse versie gebruikt. Merk op dat dit afhankelijk is van de beschikbaarheid van de geo-eigenschap (bijv. bij implementatie op Vercel).

Wereldwijd Perspectief: Zorg ervoor dat uw website meerdere talen en valuta's ondersteunt. Geef gebruikers de optie om handmatig hun voorkeurstaal of -regio te selecteren. Gebruik de juiste datums- en tijdnotaties voor elke landinstelling.

4. A/B-testen

Middleware kan worden gebruikt om A/B-testen te implementeren door gebruikers willekeurig toe te wijzen aan verschillende varianten van een pagina en hun gedrag te volgen. Hier is een vereenvoudigd voorbeeld:


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

function getRandomVariant() {
 return Math.random() < 0.5 ? 'A' : 'B';
}

export function middleware(request: NextRequest) {
 let variant = request.cookies.get('variant')?.value;

 if (!variant) {
 variant = getRandomVariant();
 const response = NextResponse.next();
 response.cookies.set('variant', variant);
 return response;
 }

 if (variant === 'B') {
 return NextResponse.rewrite(new URL('/variant-b', request.url));
 }

 return NextResponse.next();
}

export const config = {
 matcher: ['/'],
}

Deze middleware wijst gebruikers toe aan variant 'A' of 'B'. Als een gebruiker nog geen variant-cookie heeft, wordt er willekeurig een toegewezen en ingesteld. Gebruikers die zijn toegewezen aan variant 'B' worden herschreven naar de /variant-b-pagina. Vervolgens zou u de prestaties van elke variant volgen om te bepalen welke effectiever is.

Wereldwijd Perspectief: Houd rekening met culturele verschillen bij het ontwerpen van A/B-testen. Wat goed werkt in de ene regio, vindt mogelijk geen weerklank bij gebruikers in een andere. Zorg ervoor dat uw A/B-testplatform voldoet aan de privacyregelgeving in verschillende regio's.

5. Feature Flags

Met feature flags kunt u functies in uw applicatie in- of uitschakelen zonder nieuwe code te implementeren. Middleware kan worden gebruikt om te bepalen of een gebruiker toegang moet hebben tot een specifieke functie op basis van hun gebruikers-ID, locatie of andere criteria.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 // Example: Fetch feature flags from an API
 const featureFlagsResponse = await fetch('https://api.example.com/featureflags', {
 headers: {
 'X-User-Id': 'user123',
 },
 });
 const featureFlags = await featureFlagsResponse.json();

 if (featureFlags.new_feature_enabled) {
 // Enable the new feature
 return NextResponse.next();
 } else {
 // Disable the new feature (e.g., redirect to an alternative page)
 return NextResponse.redirect(new URL('/alternative-page', request.url));
 }
}

export const config = {
 matcher: ['/new-feature'],
}

Deze middleware haalt feature flags op van een API en controleert of de new_feature_enabled-vlag is ingesteld. Als dat zo is, kan de gebruiker de /new-feature-pagina openen. Anders worden ze omgeleid naar een /alternative-page.

Wereldwijd Perspectief: Gebruik feature flags om nieuwe functies geleidelijk uit te rollen naar gebruikers in verschillende regio's. Dit stelt u in staat om de prestaties te monitoren en eventuele problemen aan te pakken voordat u de functie aan een breder publiek vrijgeeft. Zorg er ook voor dat uw feature flagging-systeem wereldwijd schaalbaar is en consistente resultaten levert, ongeacht de locatie van de gebruiker. Houd rekening met regionale wettelijke beperkingen voor de uitrol van functies.

Geavanceerde Technieken

Middleware Koppelen (Chaining)

U kunt meerdere middleware-functies aan elkaar koppelen om een reeks bewerkingen op een verzoek uit te voeren. Dit kan handig zijn om complexe logica op te splitsen in kleinere, beter beheersbare modules.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const response = NextResponse.next();

 // First middleware function
 const token = request.cookies.get('auth_token');
 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 // Second middleware function
 response.headers.set('x-middleware-custom', 'value');

 return response;
}

export const config = {
 matcher: ['/dashboard/:path*'],
}

Dit voorbeeld toont twee middlewares in één. De eerste voert authenticatie uit en de tweede stelt een aangepaste header in.

Omgevingsvariabelen Gebruiken

Sla gevoelige informatie, zoals API-sleutels en databasereferenties, op in omgevingsvariabelen in plaats van ze hard te coderen in uw middleware-functies. Dit verbetert de beveiliging en maakt het beheer van de configuratie van uw applicatie eenvoudiger.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const API_KEY = process.env.API_KEY;

export async function middleware(request: NextRequest) {
 const response = await fetch('https://api.example.com/data', {
 headers: {
 'X-API-Key': API_KEY,
 },
 });

 // ...
}

export const config = {
 matcher: ['/data'],
}

In dit voorbeeld wordt de API_KEY opgehaald uit een omgevingsvariabele.

Foutafhandeling

Implementeer robuuste foutafhandeling in uw middleware-functies om te voorkomen dat onverwachte fouten uw applicatie laten crashen. Gebruik try...catch-blokken om uitzonderingen op te vangen en fouten op de juiste manier te loggen.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 try {
 const response = await fetch('https://api.example.com/data');
 // ...
 } catch (error) {
 console.error('Error fetching data:', error);
 return NextResponse.error(); // Or redirect to an error page
 }
}

export const config = {
 matcher: ['/data'],
}

Best Practices

Probleemoplossing voor Veelvoorkomende Problemen

Conclusie

Next.js middleware is een krachtig hulpmiddel voor het bouwen van dynamische en gepersonaliseerde webapplicaties. Door verzoekonderschepping te beheersen, kunt u een breed scala aan functies implementeren, van authenticatie en autorisatie tot omleiding en A/B-testen. Door de best practices in deze gids te volgen, kunt u Next.js middleware benutten om hoogwaardige, veilige en schaalbare applicaties te creëren die voldoen aan de behoeften van uw wereldwijde gebruikersbestand. Omarm de kracht van middleware om nieuwe mogelijkheden in uw Next.js-projecten te ontsluiten en uitzonderlijke gebruikerservaringen te leveren.