Next.js Middleware
Edge Middleware — auth (Clerk, Auth.js), i18n (next-intl), rate limiting (Upstash), A/B testing, geolocation i security headers.
6 zastosowań Next.js Middleware — porównanie
Autentykacja, i18n, rate limiting, A/B testing, geolocation i security headers — biblioteki, edge support i zastosowanie.
| Zastosowanie | Biblioteka | Edge | Kiedy |
|---|---|---|---|
| Autentykacja | Clerk / Auth.js v5 | Tak (JWT verify) | Ochrona /dashboard, /admin routów |
| i18n routing | next-intl / Paraglide | Tak | Wielojęzyczne app, /en /pl /de URL |
| Rate limiting | @upstash/ratelimit | Tak (Redis edge) | API protection, 429 responses |
| A/B testing | Custom cookie / Posthog | Tak | Feature experiments, UI variants |
| Geolocation | request.geo (Vercel) | Tak | Country-specific content, legal compliance |
| Security headers | Custom headers / Arcjet | Tak | CSP, XSS protection, bot blocking |
Często zadawane pytania
Co to jest Next.js Middleware i jak działa na edge?
Next.js Middleware: kod uruchamiany przed request. Edge Runtime — nie Node.js. Cloudflare Workers-like. Globalny (każdy request). Plik: middleware.ts w root projektu. export function middleware(request: NextRequest) { return NextResponse.next() }. export const config = {matcher: ['/api/:path*', '/dashboard/:path*']}. NextRequest: rozszerzony Request. URL, headers, cookies. geo — kraj, region. ip — IP klienta. NextResponse: next() — kontynuuj. redirect(url) — przekieruj. rewrite(url) — zmień URL wewnętrznie (nie widoczny dla klienta). json(data) — zwróć JSON. Headers manipulation: const response = NextResponse.next(). response.headers.set('X-Custom-Header', 'value'). Cookies manipulation: request.cookies.get('token'). response.cookies.set('session', value, {httpOnly: true}). Edge Runtime ograniczenia: brak Node.js APIs (fs, crypto full, etc.). Brak npm pakietów używających Node.js. Limit czasu wykonania (50ms). Limit wielkości (1MB). Dostępne: Fetch API, Web Crypto, TextEncoder. Config matcher: ['/dashboard/:path*'] — tylko /dashboard. ['/((?!_next/static|favicon.ico).*)'] — wszystko poza static. Matcher z has: {type: 'header', key: 'x-custom'}. Middleware stack: jedna funkcja. Brak composable middleware jak Express.
Auth middleware — ochrona routów w Next.js z Clerk, NextAuth i middleware?
Clerk middleware: import {clerkMiddleware, createRouteMatcher} from '@clerk/nextjs/server'. const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)']). export default clerkMiddleware((auth, request) => { if (!isPublicRoute(request)) auth().protect() }). Automatyczne przekierowanie do sign-in. Brak boilerplate. NextAuth v5 (Auth.js) middleware: import NextAuth from 'next-auth'. import {authConfig} from './auth.config'. export const {auth: middleware} = NextAuth(authConfig). export const config = {matcher: ['/((?!_next|_vercel|.*\..*).*)'] }. callbacks: {authorized: ({auth}) => !!auth?.user}. Custom JWT middleware: const token = request.cookies.get('auth_token')?.value. const decoded = await jose.jwtVerify(token, secret). if (!decoded) return NextResponse.redirect('/login'). jose — lightweight JWT dla Edge (bez crypto). Conditional routing: const isAuth = !!token. const isProtected = request.nextUrl.pathname.startsWith('/dashboard'). if (isProtected && !isAuth) { return NextResponse.redirect(new URL('/login', request.url)) }. Role-based access: decoded payload zawiera role. if (decoded.role !== 'admin') return NextResponse.redirect('/unauthorized'). URL rewriting z auth: rewrite do /login?redirect=URL. Po logowaniu redirect back. searchParams.get('redirect') || '/dashboard'. Middleware chaining pattern: export async function middleware(request) { const authResult = await checkAuth(request). if (!authResult.ok) return authResult.response. const rateLimitResult = await checkRateLimit(request). if (!rateLimitResult.ok) return rateLimitResult.response. return NextResponse.next() }.
Internationalization (i18n) middleware — lokalizacja w Next.js?
i18n routing w Next.js App Router: middleware wykrywa język. Rewrite do /en, /pl, /de. Brak wbudowanego i18n w App Router (inaczej niż Pages Router). Popularne podejście z next-intl: npm install next-intl. middleware.ts: import createMiddleware from 'next-intl/middleware'. export default createMiddleware({locales: ['en', 'pl', 'de'], defaultLocale: 'en'}). export const config = {matcher: ['/((?!_next|_vercel|.*\..*).*)'] }. Folder structure: app/[locale]/page.tsx. app/[locale]/layout.tsx. Messages: messages/en.json, messages/pl.json. Provider: NextIntlClientProvider messages={messages}. Hooks: useTranslations('Home'). t('title'). Locale detection: Accept-Language header. Stored cookie. Geolocation (Cloudflare geo). Custom precedence. next-i18next (Pages Router): getStaticProps z serverSideTranslations. useTranslation hook. Namespace support. Paraglide (Inlang): type-safe i18n. No bundle size overhead. Edge compatible. Lyra/Lunr multilingual search. URL structure: /en/products vs products?lang=en. SEO: hreflang tags. Sitemap per locale. canonical URL. RTL support: dir='rtl' na html. Tailwind rtl: plugin. Logical CSS properties (margin-inline-start). Arabic, Hebrew, Persian. Date/Number formatting: Intl.DateTimeFormat, Intl.NumberFormat. Per locale. Bez biblioteki.
Rate limiting i security middleware w Next.js?
Rate limiting na Edge: @upstash/ratelimit + Upstash Redis. import {Ratelimit} from '@upstash/ratelimit'. import {Redis} from '@upstash/redis'. const ratelimit = new Ratelimit({redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, '10 s')}). W middleware: const ip = request.ip || '127.0.0.1'. const {success, limit, remaining} = await ratelimit.limit(ip). if (!success) return NextResponse.json({error: 'Rate limited'}, {status: 429}). Upstash gratisowy tier: 10k req/dzień. Vercel KV (oparty na Upstash). Security headers: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy. middleware.ts lub next.config.js headers(). CSP: script-src 'self' 'nonce-xxx'. Nonce generation w middleware. Bot protection: User-Agent check. IP blocklisting. CAPTCHA redirect. Arcjet: security layer dla Next.js. Rate limit + bot protection + shield. npm install @arcjet/next. aj.withRule(arcjet.detectBot({mode: 'LIVE', allow: ['CATEGORY:SEARCH_ENGINE']})). Geoblocking: request.geo?.country. if (country === 'XX') return NextResponse.redirect('/blocked'). Cloudflare WAF zamiast (lepszy). A/B testing middleware: split cookie. const variant = request.cookies.get('variant') || randomVariant(). response.cookies.set('variant', variant). Rewrite do /app/variant-a lub /variant-b. Posthog feature flags też na edge. CORS w middleware: jeśli request.method === 'OPTIONS'. return new Response(null, {headers: {Access-Control-Allow-Origin: '*'}}). Dla API routes z zewnętrznych domen.
Middleware patterns — geolocation, A/B testing i dark mode?
Geolocation routing: request.geo.country — kod kraju (Vercel + Cloudflare). Redirect do lokalnej wersji: /pl dla PL, /de dla DE. Content personalizacja. Legal compliance — różna treść per kraj. IP geolocation (poza Vercel): MaxMind GeoIP. Edge-compatible. mmdb reader dla Edge. Cachowanie IP results. A/B testing: variant cookie w middleware. Rewrite do różnych stron. /pricing -> /pricing-variant-a lub /pricing-variant-b. Posthog Edge SDK dla flags. LaunchDarkly edge. Nie blokuj request — szybki wybór. Dark mode cookie: system preference w middleware. Cookie dla persystencji. Nie flash FOUC. request.headers.get('sec-ch-prefers-color-scheme'). Cookie: dark lub light. Header do RSC. Maintenance mode: const MAINTENANCE = process.env.MAINTENANCE_MODE === 'true'. if (MAINTENANCE && !isAdmin) return NextResponse.rewrite('/maintenance'). Admin bypass przez cookie/header. URL cleaning: lowercase URLs. Trailing slash remove/add. Canonical redirects. Starsze URL -> nowe. 301 vs 302: 301 permanentny (cachowany). 302 tymczasowy. Middleware = 302 default. NextResponse.redirect default. Dla permanentnych: {status: 301}. Preview mode: Sanity preview, Contentful preview. Draft mode (Next.js 13+). cookies().set('__prerender_bypass', '...'). Access do draft content. Passcode protection: /preview?token=SECRET. Middleware sprawdza token. Set cookie. Rewrite do draft API. Performance optimization: Middleware musi być szybkie. Brak zewnętrznych DB calls (cold start). Edge-cached data. Local lookup tables zamiast API.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz