Redirect loop di Next.js App Router hampir selalu berasal dari middleware yang mengarahkan pengguna bolak-balik antara /login, /dashboard, dan /. Perbaiki kondisi pengecekan cookie dan batasi matcher agar halaman login tidak ikut dicek, loop biasanya langsung berhenti. Kesalahan paling sering dilewatkan adalah membaca cookie token tanpa verifikasi kedaluwarsa, sehingga pengguna dianggap belum login tepat setelah login berhasil.
Penyebab Redirect Loop Paling Sering di App Router
Middleware berjalan sebelum setiap request yang cocok dengan matcher. Satu kondisi if yang salah membuat browser menerima 307 beruntun tanpa pernah merender halaman.
- Aturan saling dorong: pengguna tanpa token diarahkan ke /login, lalu /login sendiri diarahkan lagi ke / karena dianggap sudah login.
- Cookie hanya dibaca, tidak diverifikasi. Token kedaluwarsa tetap diteruskan ke dashboard, lalu dashboard melempar kembali ke login.
- Matcher terlalu luas. Middleware ikut berjalan di /login, file statis, /_next, dan API auth sehingga proses login tidak pernah selesai.
Tabel Diagnosis Redirect Loop Next Js
Buka DevTools, tab Network, lalu ulangi aksinya. Loop middleware terlihat sebagai deretan status 307 atau 308 dengan URL yang bergantian. Redirect berulang dari router.push di Client Component biasanya tidak memunculkan deretan 307 server.
| Masalah | Penyebab | Solusi |
|---|---|---|
| Login kembali ke login | Middleware memeriksa semua route | Kecualikan /login dan /_next |
| Loop hanya setelah login | Cookie kedaluwarsa tidak dicek | Validasi expiry di server |
| /dashboard dan / bergantian | Dua aturan redirect bertabrakan | Pisahkan route publik dan privat |
Langkah Memperbaiki Redirect Loop Next Js
Ikuti urutan ini agar sumber loop ketahuan, bukan sekadar hilang sementara:
- Reproduksi dengan tab samaran, catat urutan URL di Network.
- Persempit matcher hanya ke area privat seperti /dashboard/:path*.
- Perbaiki kondisi auth: route publik boleh lanjut, route privat wajib punya cookie valid.
- Hapus redirect auth dari Client Component, pindahkan ke server.
- Uji ulang alur belum login, sudah login, dan token kedaluwarsa.
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("token")?.value;
const { pathname } = request.nextUrl;
const isLoginPage = pathname === "/login";
if (!token && !isLoginPage) {
return NextResponse.redirect(new URL("/login", request.url));
}
if (token && isLoginPage) {
return NextResponse.redirect(new URL("/dashboard", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*"],
};
Setelah login, lakukan redirect bersyarat di Server Action atau Route Handler setelah cookie berhasil dipasang. Validasi cookie di Server Component memakai kode server-only, jangan mengandalkan status login dari localStorage.
FAQ
Kenapa redirect loop hanya terjadi setelah login?
Cookie gagal tersimpan atau langsung dianggap tidak valid, sehingga dashboard menolaknya dan login mengembalikannya lagi.
Apakah middleware harus memeriksa semua route?
Tidak. Batasi ke route privat agar halaman publik, aset statis, dan endpoint auth tidak ikut terpengaruh.
Kapan memakai redirect() dan kapan NextResponse.redirect()?
Gunakan NextResponse.redirect() di middleware dan redirect() di Server Component atau Server Action.