Next.js 16 Middleware 2026: Edge Runtime, Autentikasi, dan Pertanyaan Interview

Panduan lengkap tentang Next.js 16 Middleware di tahun 2026. Pelajari cara kerja Edge Runtime, implementasi autentikasi, path matching, dan persiapan pertanyaan interview frontend.

Next.js 16 Middleware Edge Runtime Authentication

Next.js 16 Middleware berjalan sebelum setiap request mencapai server, menjadikannya pertahanan pertama untuk autentikasi, lokalisasi, dan manipulasi request. Memahami middleware sangat penting untuk membangun aplikasi production dan merupakan topik yang sering muncul dalam interview frontend.

Middleware Berjalan di Edge

Next.js 16 Middleware dieksekusi di Edge Runtime secara default, yang berarti berjalan di data center terdekat dengan pengguna dengan cold start kurang dari satu milidetik. Ini menjadikannya ideal untuk pemeriksaan autentikasi dan redirect yang perlu terjadi sebelum halaman dirender.

Cara Kerja Next.js 16 Middleware

Middleware di Next.js 16 mencegat request sebelum mencapai route handler atau komponen halaman. File middleware harus ditempatkan di root proyek (sejajar dengan app/ atau pages/) dan mengekspor fungsi default yang menerima objek NextRequest.

Kendala Edge Runtime berarti middleware tidak dapat menggunakan API Node.js seperti fs atau Buffer. Middleware berjalan pada V8 isolates, mirip dengan Cloudflare Workers, yang memungkinkan distribusi global tetapi membatasi API yang tersedia hanya pada 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).*)'],
}

Konfigurasi matcher menggunakan sintaks regex-like untuk mendefinisikan path mana yang memicu middleware. Tanpa konfigurasi ini, middleware akan berjalan pada setiap request, termasuk aset statis.

Pola Autentikasi dengan Next.js Middleware

Middleware unggul dalam autentikasi karena berjalan sebelum kode halaman dieksekusi. Pengguna tanpa sesi yang valid tidak akan pernah melihat konten yang dilindungi, bahkan sekilas pun tidak. Ini berbeda dari pemeriksaan auth sisi klien yang bisa menampilkan konten terproteksi sebelum redirect.

Pola berikut memvalidasi token sesi dan mengarahkan pengguna yang tidak terautentikasi. Ini terintegrasi dengan penyedia auth mana pun yang menyimpan data sesi dalam cookies atau headers.

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
  }
}

Parameter callbackUrl menyimpan tujuan asli, sehingga pengguna akan mendarat di halaman yang awalnya diminta setelah login.

Path Matching dan Konfigurasi Matcher

Konfigurasi matcher menentukan request mana yang memicu middleware. Kesalahan dalam konfigurasi ini bisa menyebabkan masalah performa (middleware berjalan pada setiap aset statis) atau celah keamanan (path terproteksi tidak memicu pemeriksaan auth).

Next.js 16 mendukung tiga sintaks matcher: path string sederhana, pola path dengan parameter, dan pola regex-like dengan negative lookahead.

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' }],
    },
  ],
}

Kondisi has dan missing pada opsi 3 menambahkan logika sebelum middleware dijalankan. Ini lebih efisien daripada memeriksa di dalam fungsi middleware.

Siap menguasai wawancara React / Next.js Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Manipulasi Request dan Response di Middleware

Selain autentikasi, middleware dapat memodifikasi request sebelum mencapai route handler dan response sebelum mencapai klien. Use case umum termasuk menambahkan security headers, menulis ulang URL untuk A/B testing, dan menyuntikkan data geolokasi.

Kelas NextResponse menyediakan method untuk setiap jenis modifikasi. Rewrite mengubah tujuan tanpa mengubah URL browser, sementara redirect memperbarui keduanya.

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
}

Data geolokasi (request.geo) diisi oleh Vercel Edge Network. Deployment self-hosted perlu mengkonfigurasi ini melalui penyedia hosting atau menggunakan layanan geolokasi IP pihak ketiga.

URL Rewriting untuk A/B Testing dan Feature Flags

Middleware rewrite memungkinkan penyajian halaman berbeda berdasarkan cookies, headers, atau penugasan acak tanpa klien mengetahuinya. Pola ini mendukung framework A/B testing dan peluncuran fitur bertahap.

Rewrite terjadi di edge, sehingga kedua varian memiliki URL yang sama dan mendapat keuntungan dari edge caching jika sesuai.

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 mempertahankan penugasan varian, memastikan pengguna melihat versi yang sama pada kunjungan berikutnya. Kedaluwarsa 30 hari menyeimbangkan konsistensi eksperimen dengan kemampuan untuk menetapkan ulang pengguna ke eksperimen baru.

Keterbatasan Edge Runtime dan Solusinya

Edge Runtime menukar kompatibilitas Node.js dengan distribusi global dan cold start yang cepat. Middleware tidak dapat mengimpor modul khusus Node.js, yang mempengaruhi library seperti bcrypt, jsonwebtoken (saat menggunakan RS256), dan klien database yang bergantung pada soket TCP.

Dokumentasi Edge Runtime Next.js mencantumkan API yang didukung. Web Crypto, fetch, dan sebagian besar Web Platform API berfungsi. Komputasi berat harus dipindahkan ke API routes yang berjalan di 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)
}

Library jose menyediakan operasi JWT yang kompatibel dengan Edge. Library ini menggunakan Web Crypto secara internal, menghindari modul crypto Node.js.

Pertanyaan Interview Umum tentang Next.js Middleware

Pewawancara menanyakan tentang middleware untuk menilai pemahaman tentang siklus hidup request, pola keamanan, dan kendala Edge computing. Pertanyaan ini muncul dalam peran frontend dan fullstack senior yang bekerja dengan Next.js.

Di mana middleware dieksekusi dalam siklus hidup request?

Middleware berjalan setelah request mencapai server Next.js tetapi sebelum route matching atau rendering halaman. Di Vercel, middleware dieksekusi di Edge, yang berarti data center terdekat dengan pengguna. Penempatan ini menjadikannya ideal untuk autentikasi dan redirect karena request yang tidak valid tidak pernah mencapai server origin.

Apa yang tidak bisa dilakukan middleware dibandingkan dengan API routes?

Middleware berjalan di Edge Runtime, bukan Node.js. Middleware tidak dapat menggunakan modul bawaan Node.js (fs, path, crypto dengan algoritma tertentu), klien database berbasis TCP, atau paket npm yang bergantung pada API Node.js. Komputasi berat harus dilakukan di API routes atau Server Components.

Bagaimana cara menangani autentikasi di middleware tanpa blocking?

Polanya melibatkan pengecekan cookie sesi, memvalidasinya terhadap endpoint auth atau dengan memverifikasi signature JWT, dan redirect jika tidak valid. Untuk menghindari pemblokiran setiap request, gunakan konfigurasi matcher untuk hanya menjalankan middleware pada path yang dilindungi. Validasi JWT stateless lebih cepat daripada memanggil layanan auth eksternal pada setiap request.

Apa yang terjadi jika middleware melemparkan error?

Error yang tidak ditangani di middleware mengembalikan response 500 ke klien. Halaman tidak pernah dirender. Membungkus logika middleware dalam try-catch dan mengembalikan response fallback (seringkali NextResponse.next()) mencegah kegagalan request total. Mencatat error sebelum melanjutkan membantu debugging.

Untuk latihan lebih mendalam dengan konsep-konsep ini, modul pertanyaan interview Next.js Middleware dan Auth mencakup skenario tambahan.

Debugging Middleware di Development dan Production

Bug middleware sulit dilacak karena kode berjalan di edge, bukan di browser DevTools. Mode development menampilkan log middleware di terminal, tetapi production memerlukan infrastruktur logging yang tepat.

Pendekatan berikut mencatat eksekusi middleware dengan konteks yang cukup untuk debugging tanpa mengekspos data sensitif.

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()
}

Di Vercel, log ini muncul di tab Functions. Deployment self-hosted harus mengirim log ke layanan seperti Datadog atau menggunakan structured logging yang dapat dicerna platform hosting.

Best Practice Performa Middleware

Middleware berjalan pada setiap request yang cocok. Fungsi middleware yang lambat menambahkan latensi ke setiap pemuatan halaman. Tujuannya adalah menyelesaikan eksekusi middleware dalam waktu kurang dari 5ms untuk sebagian besar request.

  • Minimalkan operasi async: Setiap await menambahkan latensi. Cache hasil validasi jika memungkinkan.
  • Gunakan konfigurasi matcher: Kecualikan aset statis dan path publik yang tidak memerlukan logika middleware.
  • Hindari panggilan eksternal pada setiap request: Validasi JWT secara lokal alih-alih memanggil layanan auth. Cache hasil dalam cookies jika sesuai.
  • Jaga ukuran bundle tetap kecil: Middleware memiliki batas ukuran bundle tersendiri (1MB di Vercel). Impor hanya yang diperlukan.

Halaman teknologi React Next.js di /technologies/react-next mencakup konsep terkait seperti Server Components dan pola data fetching yang melengkapi pengetahuan middleware.

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Checklist Next.js 16 Middleware untuk Production

  • Tempatkan middleware di root proyek sebagai middleware.ts, bukan di dalam app/ atau pages/
  • Konfigurasikan matcher untuk mengecualikan _next/static, _next/image, dan aset publik dari eksekusi middleware
  • Gunakan library yang kompatibel dengan Edge untuk validasi JWT, seperti jose daripada jsonwebtoken
  • Simpan callback URL di parameter query saat redirect ke login, agar pengguna kembali ke tujuan yang dimaksud
  • Tambahkan security headers di middleware untuk aplikasi yang konsisten di semua route
  • Log eksekusi middleware dengan request ID untuk melacak request melalui sistem
  • Jaga panggilan API eksternal seminimal mungkin dengan memvalidasi token secara lokal dan menyimpan data pengguna dalam signed cookies
Tantangan harian

Bisakah kamu menemukan bug di React / Next.js?

Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Anthony Fillion-Maillet

Ditulis oleh

Anthony Fillion-Maillet

Pendiri SharpSkill

Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.

Diperbarui 20 September 2026

Tag

#nextjs
#middleware
#edge-runtime
#authentication
#interview

Bagikan

Artikel terkait