Next.js / Edge / Middleware

    Next.js Middleware

    Edge Middleware — auth (Clerk, Auth.js), i18n (next-intl), rate limiting (Upstash), A/B testing, geolocation i security headers.

    Clerk/Auth.js
    Edge auth
    next-intl
    i18n routing
    Upstash
    Rate limit
    Arcjet
    Security

    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.

    Czytaj dalej

    Powiązane artykuły

    Kontakt

    Skontaktuj się z nami

    Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

    Wyślij zapytanie

    Bezpłatna wycena w 24h
    Bez zobowiązań
    Indywidualne podejście
    Ekspresowa realizacja

    Telefon

    +48 790 814 814

    Pon-Pt: 9:00 - 18:00

    Email

    adam@fotz.pl

    Odpowiadamy w ciągu 24h

    Adres

    Plac Wolności 16

    61-739 Poznań

    Godziny pracy

    Pon - Pt9:00 - 18:00
    Sob - NdzZamknięte

    Wolisz porozmawiać?

    Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

    Zadzwoń teraz