Przejdź do treści

Middleware w Next.js — 7 zastosowań i typowych pułapek

Middleware Next.js to więcej niż auth i redirecty. Poznaj 7 zastosowań (geolokacja, testy A/B, rate limiting) i pułapki produkcyjne: matcher, p95/p99, runtime Node.

Maciej Sala

Founder StriveLab

9 min czytaniaOpublikowano 10 marca 2026 (Aktualizacja 12 lipca 2026)

Czym jest middleware w Next.js i kiedy warto go użyć?

Middleware w Next.js to funkcja uruchamiana przed routingiem dla żądań pasujących do matchera. Od Next.js 16 nowa konwencja proxy.ts działa w runtime Node.js i nie obsługuje konfiguracji runtime: 'edge'. Starsze middleware.ts korzystające z może pozostać tymczasowo podczas migracji, ale nazwa i konwencja są deprecjonowane.

Od Next.js 16 oficjalna nazwa tego mechanizmu to Proxy, a plik konwencji to proxy.ts. W starszych materiałach i istniejących projektach nadal spotkasz nazwę middleware.ts, dlatego w tym artykule używam obu określeń zamiennie.

Proxy definiujesz w jednym pliku proxy.ts w katalogu głównym projektu, a jeśli używasz struktury src/ to wewnątrz src/, na tym samym poziomie co app/. Tylko uwaga, ponieważ plik położony obok src/ zamiast w środku, nie zarejestruje się. Wtedy build przejdzie bez błędu, a proxy nie będzie działać. Plik ten przechwytuje każde żądanie pasujące do skonfigurowanego i pozwala je zmodyfikować, przekierować lub zablokować, jeszcze zanim cokolwiek trafi do klienta.

Code
// proxy.ts (w starszych projektach: middleware.ts)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
export function proxy(request: NextRequest) {
  // Logika wykonywana dla requestów pasujących do matchera
  return NextResponse.next()
}
 
export const config = {
  matcher: [
    {
      source:
        '/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
    },
  ],
}

Matcher jest analizowany statycznie, więc jego wartości muszą być stałymi zapisanymi bezpośrednio w konfiguracji. Nie kopiuj jednego negatywnego regexu do każdego projektu tylko zdecyduj, czy Proxy ma objąć Route Handlery, pliki z kropką w nazwie, metadata routes i prefetch. Każdą taką decyzję musisz pokryć testem unstable_doesProxyMatch.

7 praktycznych zastosowań middleware w Next.js

1. Autoryzacja i ochrona tras w Next.js middleware

Najczęstsze zastosowanie, czyli sprawdzenie, czy użytkownik jest zalogowany, zanim zobaczy chronioną stronę. Zamiast umieszczać logikę auth w każdym layout lub page, centralizujesz ją w middleware.

Code
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { verifySessionCookie } from '@/lib/session'
 
const protectedPaths = ['/dashboard', '/settings', '/admin']
 
function pathMatches(pathname: string, prefix: string) {
  return pathname === prefix || pathname.startsWith(`${prefix}/`)
}
 
export async function proxy(request: NextRequest) {
  const { pathname } = request.nextUrl
  const isProtected = protectedPaths.some((path) => pathMatches(pathname, path))
 
  if (!isProtected) return NextResponse.next()
 
  const token = request.cookies.get('session')?.value
 
  if (!token) {
    const loginUrl = new URL('/login', request.url)
    loginUrl.searchParams.set(
      'redirect',
      `${pathname}${request.nextUrl.search}`,
    )
    return NextResponse.redirect(loginUrl)
  }
 
  try {
    // Weryfikuje podpis/AEAD, exp, issuer i audience — nie tylko dekoduje JWT.
    await verifySessionCookie(token)
  } catch {
    return NextResponse.redirect(new URL('/login', request.url))
  }
 
  return NextResponse.next()
}

Samo dekodowanie payloadu JWT za pomocą Base64 nie stanowi weryfikacji, bo atakujący może podmienić exp, rolę i identyfikator, jeśli kod nie sprawdza kryptograficznego podpisu. Dlatego Proxy należy traktować jako optymistyczny filtr i mechanizm poprawiający UX, a nigdy jako jedyną kontrolę. Bezpieczna autoryzacja musi działać blisko danych w warstwie dostępu (DAL), Server Actions i Route Handlerach, uwzględniając przy tym uprawnienia do konkretnego zasobu.

To nie jest jedynie teoria, ponieważ CVE-2025-29927 umożliwiło ominięcie Middleware poprzez spreparowany nagłówek, a w 2026 roku opublikowano kolejne ostrzeżenia dotyczące obejścia Middleware/Proxy w określonych ścieżkach App Routera. Należy regularnie aktualizować Next.js do najnowszego wspieranego wydania i nie opierać bezpieczeństwa na założeniu, że Proxy zawsze zostanie wykonane. Zmiana matchera lub przeniesienie Server Action również może usunąć filtr brzegowy bez modyfikacji samej akcji. Gdy potrzebujesz ról i uprawnień, rozbuduj ten wzorzec według artykułu o RBAC w Next.js — role, uprawnienia i Proxy.

2. Geolokacja w middleware i treść dopasowana do lokalizacji

W Next.js 15 z NextRequest usunięto pola geo i ip, więc geolokację odczytujesz dziś najczęściej z nagłówków dodawanych przez platformę edge. Proxy może je wykorzystać do przekierowań lub ustawienia cookie z lokalizacją.

Code
export function proxy(request: NextRequest) {
  const rawCountry =
    request.headers.get('x-vercel-ip-country') ??
    request.headers.get('cf-ipcountry') ??
    'PL'
  const country = /^[A-Z]{2}$/.test(rawCountry) ? rawCountry : 'PL'
 
  const response = NextResponse.next()
  if (!request.cookies.has('country-hint')) {
    response.cookies.set('country-hint', country, {
      maxAge: 60 * 60 * 24 * 30,
      sameSite: 'lax',
      secure: true,
      path: '/',
    })
  }
 
  return response
}

Nagłówki geolokalizacyjne są rozszerzeniem platformy, a nie Next.js. Na samodzielnym hostingu mogą być nieobecne albo podatne na spoofing, jeśli reverse proxy nie usuwa wartości od klienta. Traktuj kraj jako podpowiedź do wyboru języka, waluty czy oddziału i pozwól użytkownikowi ją zmienić. Nie używaj samego IP jako dowodu rezydencji podatkowej ani jedynej kontroli wymogów prawnych. Dane lokalizacyjne, takie jak nazwa miasta, mogą pojawić się w formie zakodowanej. Należy je defensywnie dekodować, minimalizować ich retencję i zawsze uwzględniać politykę prywatności.

3. A/B testy w Next.js bez zewnętrznych narzędzi

Proxy jest dobrym miejscem do przypisania wariantu przed renderowaniem, jeśli eksperyment dotyczy routingu lub całej odpowiedzi. Pozwala uniknąć migotania treści, ale wymaga kontroli cache, botów, analityki ekspozycji i prywatności.

Code
export function proxy(request: NextRequest) {
  const cookieVariant = request.cookies.get('ab-homepage')?.value
  const existingVariant =
    cookieVariant === 'a' || cookieVariant === 'b' ? cookieVariant : null
 
  if (existingVariant) {
    // Rewrite do odpowiedniego wariantu bez zmiany URL
    const url = request.nextUrl.clone()
    url.pathname = `/variants/${existingVariant}${url.pathname}`
    return NextResponse.rewrite(url)
  }
 
  const variant = crypto.getRandomValues(new Uint8Array(1))[0] < 128 ? 'a' : 'b'
  const url = request.nextUrl.clone()
  url.pathname = `/variants/${variant}${url.pathname}`
 
  const response = NextResponse.rewrite(url)
  // Cookie ważne 30 dni — użytkownik zawsze widzi ten sam wariant
  response.cookies.set('ab-homepage', variant, {
    maxAge: 60 * 60 * 24 * 30,
    httpOnly: true,
    sameSite: 'lax',
    secure: true,
  })
 
  return response
}

Nigdy nie umieszczaj w ścieżce niezwalidowanej wartości cookie, która mogłaby spowodować nieoczekiwane przepisywanie adresów (rewrite'y). Wariant przypisuj wyłącznie do tras objętych eksperymentem, pomijając zasoby statyczne, API i boty. Identyfikator eksperymentu i ekspozycję rejestruj dopiero w momencie faktycznego wyświetlenia wariantu, ponieważ samo jego przypisanie nie jest jeszcze konwersją. Pamiętaj, że przepisywanie adresów (rewrite) i użycie plików cookie mogą wpływać na klucz cache, dlatego kluczowe jest przetestowanie, czy warianty nie mieszają się w CDN i czy adres kanoniczny pozostaje publicznym URL-em, a nie wewnętrzną ścieżką typu /variants/....

4. Rate limiting w middleware na poziomie proxy

Limiter musi używać stanu, którego klient nie może wyzerować, i który jest współdzielony przez instancje. Cookie nie spełnia żadnego z tych warunków. Przykład z rozproszonym magazynem może wyglądać tak:

Code
import { Ratelimit } from '@upstash/ratelimit'
import { Redis } from '@upstash/redis'
 
const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(60, '1 m'),
  prefix: 'ratelimit:api',
})
 
export async function proxy(request: NextRequest) {
  if (!request.nextUrl.pathname.startsWith('/api')) {
    return NextResponse.next()
  }
 
  // Użyj identyfikatora dostarczanego przez zaufaną platformę albo userId.
  const identifier = getTrustedClientIdentifier(request)
  const result = await ratelimit.limit(identifier)
 
  if (!result.success) {
    return NextResponse.json(
      { error: 'Zbyt wiele żądań. Spróbuj ponownie za chwilę.' },
      {
        status: 429,
        headers: {
          'Retry-After': String(
            Math.max(1, Math.ceil((result.reset - Date.now()) / 1000)),
          ),
          'RateLimit-Limit': String(result.limit),
          'RateLimit-Remaining': String(result.remaining),
          'RateLimit-Reset': String(Math.ceil(result.reset / 1000)),
        },
      },
    )
  }
 
  return NextResponse.next()
}

Nie ufaj pierwszej wartości dowolnego x-forwarded-for, dopóki nie znasz łańcucha zaufanych proxy, ponieważ klient może wysłać własny nagłówek. Dla operacji po zalogowaniu lepszy bywa userId, a dla logowania kombinacja IP, konta i szerszych zabezpieczeń anty-bot. Limiter w Proxy chroni szeroki brzeg, ale kosztowne lub finansowe operacje powinny mieć dodatkowy limit w samej Server Action/Route Handlerze. Ustal zachowanie przy awarii magazynu np fail-open dla publicznej treści i fail-closed dla wrażliwej operacji mogą być właściwymi, ale różnymi decyzjami. Pełną implementację pokazuje rate limiting w Next.js z Upstash.

5. Dynamiczne redirecty i rewrite'y w Next.js

Middleware pozwala centralnie zarządzać przekierowaniami bez modyfikowania next.config.ts co jest szczególnie przydatne, gdy lista redirectów pochodzi z CMS lub bazy danych. Poza tym, przy migracji, gdy musisz przepiąć setki starych URL-i, a jak robić to bez utraty pozycji w Google, opisuje migracja z WordPressa na Next.js — redirecty 301 i pozycje SEO.

Code
// Mapa redirectów — może pochodzić z cache lub KV store
const redirects: Record<string, string> = {
  '/stara-strona': '/nowa-strona',
  '/blog/stary-post': '/blog/nowy-post',
  '/uslugi': '/oferta',
  '/kontakt-formularz': '/kontakt',
}
 
export function proxy(request: NextRequest) {
  const { pathname } = request.nextUrl
 
  // Sprawdź, czy istnieje redirect
  const destination = redirects[pathname]
  if (destination) {
    const target = new URL(destination, request.url)
 
    // Dla tej mapy dopuszczamy tylko własny origin i unikamy pętli.
    if (
      target.origin === request.nextUrl.origin &&
      target.pathname !== pathname
    ) {
      return NextResponse.redirect(target, 308)
    }
  }
 
  return NextResponse.next()
}

Dwie rzeczy warto wiedzieć przy tym wzorcu. Po pierwsze, headers i redirects z next.config.ts wykonują się przed Proxy. Statyczne przekierowania trzymaj w konfiguracji, a Proxy zostaw dla mapy dostępnej bez wolnego zapytania do CMS przy każdym requestcie — np. zsynchronizowanej do KV/cache. Po drugie, waliduj origin, protokół, pętle i łańcuchy przekierowań. Dla trwałej zmiany adresu użyj 308; 307 zachowuje metodę przy przekierowaniu tymczasowym. Normalizację trailing slash Next.js wykonuje domyślnie, chyba że ustawisz skipTrailingSlashRedirect.

6. Nagłówki bezpieczeństwa ustawiane w middleware

Stałe nagłówki bezpieczeństwa najprościej ustawić w headers() w next.config.ts albo na reverse proxy i to bez uruchamiania kodu dla każdego requestu. Proxy jest potrzebne, gdy polityka jest zależna od żądania, np. generuje unikalny nonce CSP.

Code
export function proxy(request: NextRequest) {
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
  const isDev = process.env.NODE_ENV === 'development'
  const csp = `
    default-src 'self';
    script-src 'self' 'nonce-${nonce}' 'strict-dynamic'${isDev ? " 'unsafe-eval'" : ''};
    style-src 'self' 'nonce-${nonce}';
    img-src 'self' data: https:;
    object-src 'none';
    base-uri 'self';
    form-action 'self';
    frame-ancestors 'none';
  `
    .replace(/\s{2,}/g, ' ')
    .trim()
 
  const requestHeaders = new Headers(request.headers)
  requestHeaders.set('Content-Security-Policy', csp)
  requestHeaders.set('x-nonce', nonce)
 
  const response = NextResponse.next({
    request: { headers: requestHeaders },
  })
 
  response.headers.set('Content-Security-Policy', csp)
  response.headers.set('X-Content-Type-Options', 'nosniff')
  response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
  response.headers.set(
    'Permissions-Policy',
    'camera=(), microphone=(), geolocation=(self)',
  )
 
  return response
}

Poprzednia polityka z script-src 'unsafe-inline' dawała XSS znacznie szersze pole i nie była przykładem mocnego CSP. Next.js odczytuje nonce z CSP obecnego w nagłówku żądania, a tę samą politykę trzeba wysłać w odpowiedzi. Nonce wymusza dynamiczne renderowanie objętych stron i wpływa na cache, więc najpierw wdrażaj Content-Security-Policy-Report-Only, analizuj raporty i ogranicz matcher. frame-ancestors 'none' jest współczesną ochroną clickjacking; X-Frame-Options: DENY możesz zachować dla starszych klientów. HSTS dodawaj wyłącznie po HTTPS i po audycie wszystkich subdomen.

7. Logowanie i analytics bez blokowania odpowiedzi

Dzięki API after z next/server (stabilne od Next.js 15.1) możesz zaplanować pracę po zakończeniu odpowiedzi. Platforma musi jednak podtrzymać invocation przez mechanizm zgodny z waitUntil; wsparcie adapterów nie jest automatyczne. after ma limit czasu platformy, uruchamia się również po błędzie i nie jest trwałą kolejką. Używaj go do telemetryki, którą można utracić lub ponowić; zdarzenia biznesowe zapisuj transakcyjnie do outboxa/kolejki przed odpowiedzią.

Code
import { NextResponse } from 'next/server'
import { after } from 'next/server'
 
export function proxy(request: NextRequest) {
  const response = NextResponse.next()
 
  after(async () => {
    // Ten kod wykonuje się PO wysłaniu odpowiedzi
    const logData = {
      path: sanitizePathForTelemetry(request.nextUrl.pathname),
      method: request.method,
      timestamp: new Date().toISOString(),
    }
 
    try {
      await fetch('https://logs.example.com/ingest', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(logData),
        signal: AbortSignal.timeout(1000),
      })
    } catch {
      // Telemetria best-effort nie może zmienić wyniku requestu.
    }
  })
 
  return response
}

Nie wysyłaj automatycznie pełnego URL-a, query stringa, cookie, IP ani user-agenta. Mogą zawierać identyfikatory i dane osobowe. Zdefiniuj allowlistę pól, retencję, sampling i podstawę prawną; sekrety oraz nagłówki autoryzacji zawsze redaguj. Jeśli potrzebujesz śladu audytowego dla zmiany danych, zapis best-effort w after jest niewystarczający.

Dobre praktyki i ograniczenia middleware w Next.js

Czego unikać w middleware, żeby nie spowolnić aplikacji

  • Ciężkich operacji. Nie ma uniwersalnego limitu 50 ms, po prostu mierz budżet p95/p99. Unikaj bazy i zewnętrznego API na ścieżce każdego requestu.

  • Dużych zależności. proxy.ts w Next.js 16 działa w Node.js, ale nadal jest granicą sieciową wykonywaną często. Starsze middleware.ts na Edge ma węższe API. Nie projektuj kodu na przecięciu obu runtime'ów bez testów adaptera. Szerszy kontekst opisuje Edge Runtime w Next.js — kiedy edge, a kiedy Node.

  • Nadmiarowego matchera. Im precyzyjniej zdefiniujesz matcher, tym mniej niepotrzebnych wywołań middleware.

Wzorzec chain: jak łączyć wiele middleware w Next.js

Gdy masz wiele odpowiedzialności, zamiast jednej rozbudowanej funkcji, stwórz chain:

Code
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
type ProxyStep = (
  request: NextRequest,
  response: NextResponse,
) => Response | void | Promise<Response | void>
 
async function chain(
  functions: ProxyStep[],
  request: NextRequest,
): Promise<Response> {
  const response = NextResponse.next()
 
  for (const fn of functions) {
    const terminalResponse = await fn(request, response)
    if (terminalResponse) return terminalResponse
  }
 
  return response
}
 
// Poszczególne middleware
function withAuth(request: NextRequest, response: NextResponse) {
  // Zwróć redirect/401 tylko wtedy, gdy łańcuch ma się zakończyć.
  if (shouldRedirect(request)) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
}
 
function withSecurityHeaders(request: NextRequest, response: NextResponse) {
  response.headers.set('X-Frame-Options', 'DENY')
}
 
function withLogging(request: NextRequest, response: NextResponse) {
  console.log(`[${request.method}] ${request.nextUrl.pathname}`)
}
 
export async function proxy(request: NextRequest) {
  return chain([withAuth, withSecurityHeaders, withLogging], request)
}

W poprzednim wariancie każdy krok zwracał NextResponse, co skutkowało zakończeniem łańcucha po pierwszej funkcji, ponieważ NextResponse jest instancją Response. Zgodnie z poprawionym kontraktem, kroki modyfikujące wspólną odpowiedź nie zwracają nic. Tylko przekierowanie, przepisanie lub blokada stanowią odpowiedź terminalną. W przypadku bardziej złożonych operacji przepisywania, jawny pipeline z typami wyników może być korzystniejszym rozwiązaniem.

Proxy w Next.js: dodatkowe możliwości i realne ograniczenia

Lista siedmiu zastosowań nie wyczerpuje tematu, dwa wzorce zasługują na wzmiankę, ponieważ w praktyce ratują konkretne architektury:

  • CORS dla API. Proxy może centralnie obsługiwać żądania preflight i nagłówki dla wielu Route Handlerów. Należy jednak pamiętać, że lista dozwolonych originów, metod i nagłówków musi być wąska. Nie powinno się zwracać dowolnego Origin wraz z credentials, ale zamiast tego dodać Vary: Origin.

  • Multi-tenancy. Przepisanie subdomeny na ścieżkę (np. klient.twoja-apka.pl na /tenants/klient/...) upraszcza routing, ale aby Host należał do dozwolonej domeny, a tenant był mapowany z zaufanej konfiguracji. Ponadto, każda operacja na danych musi nadal wymuszać tenantId, ponieważ samo przepisanie adresu nie zapewnia izolacji danych.

Od Next.js 15.1 proxy da się też testować jednostkowo. Pakiet next/experimental/testing/server udostępnia m.in. unstable_doesProxyMatch do sprawdzenia, czy matcher obejmuje daną ścieżkę, oraz helpery isRewrite i getRewrittenUrl do asercji na wyniku całej funkcji.

Na koniec, sam zespół Next.js rekomenduje traktować Proxy jako ostateczność i nie powinnien być pierwszym wybór. Co ciekawe, zmiana nazwy z „middleware" ma m.in. zniechęcić do upychania tam logiki, którą lepiej obsłużą dedykowane API frameworka: przekierowania w next.config.ts, autoryzacja w Server Components, nagłówki per route. Siedem zastosowań z tego artykułu to sytuacje, w których centralny punkt przed requestem jest korzystne, a jeśli da się coś zrobić bliżej samej trasy to zrób to tam. Nie kombinuj.

Elastyczne i wydajne narzędzia dla biznesu, które dotrzymają kroku Twojemu rozwojowi.
Next.js

Często zadawane pytania

Czy middleware (proxy) w Next.js spowalnia stronę?

Każde pasujące żądanie przechodzi przez Proxy przed routingiem, więc jego koszt trafia na ścieżkę krytyczną. Nie istnieje uniwersalny bezpieczny limit 50 ms — mierz p95/p99 na swojej platformie. Ogranicz matcher, unikaj zdalnych odczytów i trzymaj logikę deterministyczną oraz odporną na awarie.

Czy mogę mieć kilka plików middleware?

Nie. Obsługiwany jest jeden plik proxy.ts w głównym katalogu projektu albo w src/, jeśli używasz tej struktury (w starszych projektach middleware.ts). Jeśli potrzebujesz modularności, użyj wzorca chain — łączysz kilka funkcji w jeden łańcuch wykonywany po kolei.

Czy middleware działa na statycznych stronach?

Tak, jeśli URL pasuje do matchera i wdrożenie obsługuje Proxy. Może działać przed odpowiedzią statyczną, SSR, ISR czy Route Handlerem, ale nie oznacza to automatycznie „każdego żądania” — matcher powinien wykluczać assety, assety i trasy, które go nie potrzebują. Prefetch trzeba rozstrzygnąć świadomie: auth może chcieć go objąć, a kosztowna personalizacja pominąć. Static export nie obsługuje Proxy.

Jakie API jest dostępne w middleware?

W Next.js 16 proxy.ts działa w runtime Node.js i nie można skonfigurować runtime: edge. Starsze middleware.ts może pozostać na Edge Runtime podczas migracji, ale jest deprecjonowane. Dostępność, limity czasu i zachowanie API zależą dodatkowo od adaptera oraz platformy wdrożeniowej.

Czym proxy.ts różni się od middleware.ts?

To ta sama funkcja pod nową nazwą. Od Next.js 16 mechanizm nazywa się Proxy, a plik konwencji to proxy.ts (eksport funkcji proxy). middleware.ts jest deprecjonowane — Next.js dostarcza codemod, który automatycznie zmienia nazwę pliku i funkcji.

O autorze

Maciej Sala

Maciej Sala — konsultant technologiczny produktów cyfrowych i web developer z bogatym doświadczeniem w marketingu internetowym oraz SEO. Na co dzień pracuje z Reactem, Next.js i TypeScriptem, a ostatnio także z Astro i narzędziami do automatyzacji procesów AI. Sprawnie łączy perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat był związany z branżą gier wideo jako project manager i game designer. Absolwent historii na Uniwersytecie Jagiellońskim oraz studiów podyplomowych z marketingu internetowego na AGH w Krakowie. Po godzinach trenuje na siłowni, maluje figurki i rozwija własne projekty.

Pomagam przekładać takie tematy na konkretne wdrożenia w frontendzie, SEO, analityce i procesie produktowym.

Skontaktuj się ze mną

Biblioteka wiedzy na temat Next.js

Czytaj dalej

Zobacz więcej wpisów
Edge Runtime w Next.js — kiedy Edge, a kiedy Node?

Edge Runtime obiecuje błyskawiczne działanie kodu tuż przy użytkowniku. To ultralekkie środowisko, oparte na V8 Isolates i rozproszone globalnie, eliminuje cold start , bo nie wymaga rozgrzewania ciężkich maszyn wirtualnych. Przez lata wydawało się to jedynym słusznym kierunkiem, ale dzisiaj jednak, w Next.js 16, automatyczny wybór Edge może okazać się strategicznym błędem.

Maciej Sala

Maciej Sala

Founder StriveLab

Rate limiting na Edge w Next.js z Upstash

Jeden bot, jedna pętla z błędem albo jeden zdeterminowany atakujący — i Twoje API dostaje tysiące żądań na minutę. Serwer się dławi, rachunek za infrastrukturę rośnie, a normalni użytkownicy widzą błędy. Rate limiting ogranicza liczbę żądań z jednego źródła w oknie czasu. Pokazuję, jak wdrożyć go w Next.js z Upstash Redis — w Proxy, Route Handlerach i Server Actions, z trzema algorytmami i limitami per endpoint. W Next.js 16 proxy.ts działa jednak w Node.js, więc „na Edge” dotyczy Route Handlera z Edge Runtime albo infrastruktury dostawcy, nie samej konwencji Proxy.

Maciej Sala

Maciej Sala

Founder StriveLab

Wielojęzyczna strona w Next.js App Router (i18n)

W Pages Router Next.js miał wbudowane wsparcie dla i18n i wystarczyło dodać konfigurację i18n w next.config.js , by framework zarządzał routingiem językowym automatycznie. App Router nie ma tego mechanizmu i właśnie dlatego i18n trzeba zaimplementować samodzielnie lub użyć do tego celu biblioteki. Artykuł jest o zbudowaniu wielojęzycznej strony w Next.js.

Maciej Sala

Maciej Sala

Founder StriveLab