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 — Product Manager i Frontend 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 rozwijam 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
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

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

Vercel vs Coolify vs VPS — gdzie hostować Next.js w 2026?

Next.js można wdrożyć jako statyczny eksport, pojedynczy serwer Node.js, kontener Docker albo aplikację na zarządzanej platformie. Wybór hostingu nie polega więc na pytaniu, czy framework „zadziała”, lecz kto będzie odpowiadał za wdrożenia, cache, skalowanie, bezpieczeństwo, koszty oraz przetwarzanie danych.

Maciej Sala

Maciej Sala

Founder StriveLab