Next.js 16 Middleware w 2026: Edge Runtime, Uwierzytelnianie i Pytania Rekrutacyjne

Kompleksowy przewodnik po Next.js 16 Middleware obejmujacy Edge Runtime, wzorce uwierzytelniania i pytania rekrutacyjne.

Next.js 16 Middleware w 2026: Edge Runtime, Uwierzytelnianie i Pytania Rekrutacyjne

Next.js 16 Middleware wykonuje sie przed kazdym zadaniem zanim dotrze ono do serwera, stanowiac pierwsza linie obrony dla uwierzytelniania, lokalizacji i manipulacji zadaniami. Zrozumienie middleware jest kluczowe dla budowania aplikacji produkcyjnych i stanowi czesty temat na rozmowach rekrutacyjnych dla frontend developerow.

Middleware dziala na Edge

Next.js 16 Middleware domyslnie wykonuje sie w Edge Runtime, co oznacza, ze dziala w centrach danych blisko uzytkownikow z czasem zimnego startu ponizej milisekundy. To sprawia, ze jest idealny do sprawdzania uwierzytelniania i przekierowan, ktore musza nastapic przed renderowaniem strony.

Jak dziala Next.js 16 Middleware pod maska

Middleware w Next.js 16 przechwytuje zadania zanim dotra do handlera trasy lub komponentu strony. Plik middleware musi byc umieszczony w katalogu glownym projektu (obok app/ lub pages/) i eksportowac domyslna funkcje, ktora otrzymuje obiekt NextRequest.

Ograniczenie Edge Runtime oznacza, ze middleware nie moze uzywac API Node.js takich jak fs czy Buffer. Dziala na izolatkach V8, podobnie jak Cloudflare Workers, co umozliwia globalna dystrybucje, ale ogranicza dostepne API do Web Standards.

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

export function middleware(request: NextRequest) {
  // Access request headers, cookies, and URL
  const token = request.cookies.get('session')?.value
  const pathname = request.nextUrl.pathname

  // Log for debugging (visible in Vercel logs)
  console.log(`Middleware: ${request.method} ${pathname}`)

  // Continue to the route handler
  return NextResponse.next()
}

// Configure which paths trigger middleware
export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}

Konfiguracja matcher uzywa skladni podobnej do regex, aby zdefiniowac, ktore sciezki uruchamiaja middleware. Bez niej middleware dziala na kazdym zadaniu, wlacznie z zasobami statycznymi.

Wzorce uwierzytelniania z Next.js Middleware

Middleware swietnie sprawdza sie w uwierzytelnianiu, poniewaz wykonuje sie przed uruchomieniem jakiegokolwiek kodu strony. Uzytkownik bez waznej sesji nigdy nie zobaczy chronionej tresci, nawet przez ulamek sekundy. To rozni sie od sprawdzania auth po stronie klienta, ktore moze przez moment pokazac chroniona tresc przed przekierowaniem.

Ponizszy wzorzec waliduje token sesji i przekierowuje nieuwierzytelnionych uzytkownikow. Integruje sie z dowolnym dostawca auth, ktory przechowuje dane sesji w cookies lub naglowkach.

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

const protectedPaths = ['/dashboard', '/settings', '/profile']
const authPaths = ['/login', '/signup']

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl
  const sessionToken = request.cookies.get('session')?.value

  // Check if path requires authentication
  const isProtectedPath = protectedPaths.some(path => 
    pathname.startsWith(path)
  )
  const isAuthPath = authPaths.some(path => 
    pathname.startsWith(path)
  )

  // Validate session token (call auth service)
  const isValidSession = sessionToken 
    ? await validateSession(sessionToken)
    : false

  // Redirect unauthenticated users to login
  if (isProtectedPath && !isValidSession) {
    const loginUrl = new URL('/login', request.url)
    loginUrl.searchParams.set('callbackUrl', pathname)
    return NextResponse.redirect(loginUrl)
  }

  // Redirect authenticated users away from auth pages
  if (isAuthPath && isValidSession) {
    return NextResponse.redirect(new URL('/dashboard', request.url))
  }

  return NextResponse.next()
}

async function validateSession(token: string): Promise<boolean> {
  // Call auth API endpoint or decode JWT
  // Edge-compatible: use fetch, not Node.js crypto
  try {
    const response = await fetch('https://api.example.com/validate', {
      headers: { Authorization: `Bearer ${token}` },
    })
    return response.ok
  } catch {
    return false
  }
}

Parametr callbackUrl zachowuje oryginalny cel, wiec uzytkownicy trafiaja na strone, ktora poczatkowo zadali, po zalogowaniu.

Dopasowywanie sciezek i konfiguracja Matchera

Konfiguracja matcher okresla, ktore zadania uruchamiaja middleware. Bledna konfiguracja prowadzi do problemow z wydajnoscia (middleware dzialajacy na kazdym zasobie statycznym) lub luk bezpieczenstwa (chronione sciezki nie uruchamiajace sprawdzania auth).

Next.js 16 obsluguje trzy skladnie matchera: sciezki tekstowe, wzorce sciezek z parametrami oraz wzorce podobne do regex z negatywnymi lookaheadami.

middleware.tstypescript
// Option 1: Simple string paths
export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*'],
}

// Option 2: Exclude static assets with negative lookahead
export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico|public/).*)'],
}

// Option 3: Conditional matching with has/missing
export const config = {
  matcher: [
    {
      source: '/api/:path*',
      has: [{ type: 'header', key: 'Authorization' }],
    },
    {
      source: '/dashboard/:path*',
      missing: [{ type: 'cookie', key: 'session' }],
    },
  ],
}

Warunki has i missing w opcji 3 dodaja logike jeszcze przed uruchomieniem middleware. To jest bardziej wydajne niz sprawdzanie wewnatrz funkcji middleware.

Gotowy na rozmowy o React / Next.js?

Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.

Manipulacja zadaniami i odpowiedziami w Middleware

Poza uwierzytelnianiem, middleware moze modyfikowac zadania przed dotarciem do handlerow tras oraz odpowiedzi przed dotarciem do klienta. Typowe przypadki uzycia obejmuja dodawanie naglowkow bezpieczenstwa, przepisywanie URL dla testow A/B oraz wstrzykiwanie danych geolokalizacyjnych.

Klasa NextResponse dostarcza metody dla kazdego typu modyfikacji. Przepisania (rewrites) zmieniaja cel bez zmiany URL w przegladarce, podczas gdy przekierowania aktualizuja oba.

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

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

  // Add security headers to all responses
  response.headers.set('X-Frame-Options', 'DENY')
  response.headers.set('X-Content-Type-Options', 'nosniff')
  response.headers.set(
    'Referrer-Policy', 
    'strict-origin-when-cross-origin'
  )

  // Inject geolocation into request headers for route handlers
  const geo = request.geo
  if (geo?.country) {
    response.headers.set('x-user-country', geo.country)
    response.headers.set('x-user-city', geo.city ?? 'unknown')
  }

  return response
}

Dane geolokalizacyjne (request.geo) sa wypelniane przez Vercel Edge Network. Wdrozenia self-hosted musza to skonfigurowac przez dostawce hostingu lub uzyc zewnetrznego serwisu geolokalizacji IP.

Przepisywanie URL dla testow A/B i flag funkcji

Przepisywanie w middleware pozwala serwowac rozne strony na podstawie cookies, naglowkow lub losowego przypisania, bez wiedzy klienta. Ten wzorzec zasila frameworki do testow A/B i stopniowe wdrazanie funkcji.

Przepisanie nastepuje na edge, wiec oba warianty maja ten sam URL i korzystaja z cache na edge, gdy jest to odpowiednie.

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

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl

  // Check for existing variant assignment
  let variant = request.cookies.get('ab-variant')?.value

  // Assign variant if not set (50/50 split)
  if (!variant && pathname === '/pricing') {
    variant = Math.random() < 0.5 ? 'control' : 'treatment'
    const response = NextResponse.rewrite(
      new URL(`/pricing/${variant}`, request.url)
    )
    response.cookies.set('ab-variant', variant, {
      maxAge: 60 * 60 * 24 * 30, // 30 days
      httpOnly: true,
    })
    return response
  }

  // Rewrite to assigned variant
  if (variant && pathname === '/pricing') {
    return NextResponse.rewrite(
      new URL(`/pricing/${variant}`, request.url)
    )
  }

  return NextResponse.next()
}

Cookie przechowuje przypisanie wariantu, zapewniajac, ze uzytkownicy widza te sama wersje przy kolejnych wizytach. 30-dniowe wygasniecie rownowazy spojnosc eksperymentu z mozliwoscia przypisania uzytkownikow do nowych eksperymentow.

Ograniczenia Edge Runtime i obejscia

Edge Runtime wymienia kompatybilnosc z Node.js na globalna dystrybucje i szybkie zimne starty. Middleware nie moze importowac modulow specyficznych dla Node.js, co wplywa na biblioteki takie jak bcrypt, jsonwebtoken (przy uzyciu RS256) oraz klientow baz danych opartych na gniazdach TCP.

Dokumentacja Edge Runtime Next.js wymienia obslugiwane API. Web Crypto, fetch i wiekszosc API platformy webowej dziala. Ciezkie obliczenia powinny byc przenoszone do API routes dzialajacych w Node.js.

middleware.ts - JWT validation without jsonwebtokentypescript
import { jwtVerify } from 'jose' // Edge-compatible JWT library
import type { NextRequest } from 'next/server'

const JWT_SECRET = new TextEncoder().encode(process.env.JWT_SECRET!)

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

  if (!token) {
    return redirectToLogin(request)
  }

  try {
    // jose library works in Edge Runtime
    const { payload } = await jwtVerify(token, JWT_SECRET)
    
    // Token is valid, check expiration
    if (payload.exp && payload.exp < Date.now() / 1000) {
      return redirectToLogin(request)
    }

    return NextResponse.next()
  } catch {
    // Invalid token signature or format
    return redirectToLogin(request)
  }
}

function redirectToLogin(request: NextRequest) {
  const url = new URL('/login', request.url)
  url.searchParams.set('callbackUrl', request.nextUrl.pathname)
  return NextResponse.redirect(url)
}

Biblioteka jose zapewnia operacje JWT kompatybilne z Edge. Pod spodem uzywa Web Crypto, unikajac modulu crypto z Node.js.

Najczestsze pytania rekrutacyjne o Next.js Middleware

Rekruterzy pytaja o middleware, aby ocenic zrozumienie cyklu zycia zadan, wzorcow bezpieczenstwa i ograniczen Edge computing. Te pytania pojawiaja sie na stanowiskach senior frontend i fullstack pracujacych z Next.js.

Gdzie w cyklu zycia zadania wykonuje sie middleware?

Middleware dziala po tym, jak zadanie dotrze do serwera Next.js, ale przed jakimkolwiek dopasowaniem trasy lub renderowaniem strony. Na Vercel wykonuje sie na Edge, czyli w najblizszym centrum danych wzgledem uzytkownika. To umiejscowienie sprawia, ze jest idealny do uwierzytelniania i przekierowan, poniewaz nieprawidlowe zadania nigdy nie docieraja do serwera origin.

Czego middleware nie moze robic w porownaniu do API routes?

Middleware dziala w Edge Runtime, nie w Node.js. Nie moze uzywac wbudowanych modulow Node.js (fs, path, crypto z niektorymi algorytmami), klientow baz danych opartych na TCP ani pakietow npm zaleznych od API Node.js. Ciezkie obliczenia powinny odbywac sie w API routes lub Server Components.

Jak obslugiwac uwierzytelnianie w middleware bez blokowania?

Wzorzec polega na sprawdzeniu cookie sesji, walidacji go wzgledem endpointu auth lub weryfikacji podpisu JWT, i przekierowaniu jesli jest nieprawidlowy. Aby uniknac blokowania kazdego zadania, nalezy uzyc konfiguracji matcher, aby middleware dzialal tylko na chronionych sciezkach. Bezstanowa walidacja JWT jest szybsza niz wywolywanie zewnetrznego serwisu auth przy kazdym zadaniu.

Co sie dzieje, gdy middleware wyrzuci blad?

Nieobsluzony blad w middleware zwraca odpowiedz 500 do klienta. Strona nigdy sie nie renderuje. Owiniecie logiki middleware w try-catch i zwrocenie fallback response (czesto NextResponse.next()) zapobiega calkowitym awariom zadan. Logowanie bledu przed kontynuowaniem pomaga w debugowaniu.

Dla glebszej praktyki z tymi koncepcjami, modul pytan rekrutacyjnych o Next.js Middleware i Auth obejmuje dodatkowe scenariusze.

Debugowanie Middleware w Development i Production

Bledy w middleware sa trudne do znalezienia, poniewaz kod dziala na edge, nie w DevTools przegladarki. Tryb development pokazuje logi middleware w terminalu, ale produkcja wymaga odpowiedniej infrastruktury logowania.

Ponizsze podejscie loguje wykonanie middleware z wystarczajacym kontekstem do debugowania problemow bez ujawniania wrazliwych danych.

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

export function middleware(request: NextRequest) {
  const start = Date.now()
  const requestId = crypto.randomUUID()

  // Log request start
  console.log(JSON.stringify({
    type: 'middleware_request',
    requestId,
    method: request.method,
    path: request.nextUrl.pathname,
    userAgent: request.headers.get('user-agent')?.slice(0, 100),
    country: request.geo?.country,
  }))

  // Process request
  const response = processRequest(request)

  // Log completion
  console.log(JSON.stringify({
    type: 'middleware_response',
    requestId,
    duration: Date.now() - start,
    status: response.status,
  }))

  // Pass request ID to route handlers
  response.headers.set('x-request-id', requestId)
  return response
}

function processRequest(request: NextRequest): NextResponse {
  // Middleware logic here
  return NextResponse.next()
}

Na Vercel te logi pojawiaja sie w zakladce Functions. Wdrozenia self-hosted powinny wysylac logi do serwisu takiego jak Datadog lub uzywac strukturyzowanego logowania, ktore platforma hostingowa moze przetworzyc.

Najlepsze praktyki wydajnosci Middleware

Middleware dziala na kazdym dopasowanym zadaniu. Wolna funkcja middleware dodaje opoznienie do kazdego ladowania strony. Celem jest zakonczenie wykonania middleware w czasie ponizej 5ms dla wiekszosci zadan.

  • Minimalizuj operacje async: Kazdy await dodaje opoznienie. Gdy to mozliwe, cachuj wyniki walidacji.
  • Uzywaj konfiguracji matcher: Wyklucz zasoby statyczne i publiczne sciezki, ktore nie potrzebuja logiki middleware.
  • Unikaj zewnetrznych wywolan przy kazdym zadaniu: Waliduj JWT lokalnie zamiast wywolywac serwis auth. Gdy to odpowiednie, cachuj wyniki w cookies.
  • Utrzymuj maly bundle: Middleware ma wlasny limit rozmiaru bundle (1MB na Vercel). Importuj tylko to, co potrzebne.

Strona technologii React Next.js pod adresem /technologies/react-next obejmuje powiazane koncepcje jak Server Components i wzorce pobierania danych, ktore uzupelniaja wiedze o middleware.

Zacznij ćwiczyć!

Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.

Checklista Next.js 16 Middleware dla produkcji

  • Umiesc middleware w katalogu glownym projektu jako middleware.ts, nie wewnatrz app/ ani pages/
  • Skonfiguruj matcher, aby wykluczyc _next/static, _next/image i publiczne zasoby z wykonania middleware
  • Uzywaj bibliotek kompatybilnych z Edge do walidacji JWT, takich jak jose zamiast jsonwebtoken
  • Przechowuj callback URL w parametrach query podczas przekierowania do logowania, aby uzytkownicy wracali do zamierzonego celu
  • Dodawaj naglowki bezpieczenstwa w middleware dla spojnego stosowania we wszystkich trasach
  • Loguj wykonanie middleware z ID zadan, aby sledzic zadania przez system
  • Ogranicz zewnetrzne wywolania API do minimum przez lokalna walidacje tokenow i cachowanie danych uzytkownika w podpisanych cookies
Wyzwanie dnia

Znajdziesz błąd w React / Next.js?

Prawdziwy fragment kodu, ukryty błąd, jedna próba dziennie. Bez konta, żeby spróbować.

Anthony Fillion-Maillet

Autor:

Anthony Fillion-Maillet

Założyciel SharpSkill

Programista fullstack od ponad 10 lat. Prowadzi SharpSkill i odpowiada za wszystko, co się tu ukazuje.

Zaktualizowano 20 września 2026

Udostępnij

Powiązane artykuły