Gunakan redirect() dari next/navigation kalau kode berjalan di server, dan gunakan useRouter().push() kalau kode berjalan di browser. Salah pilih lapisan ini penyebab redirect di App Router paling sering gagal. middleware dan Route Handler memakai NextResponse.redirect().
Pilih Metode Redirect Sesuai Tempat Kode Berjalan
App Router memisahkan kode server dan client secara ketat. API navigasi mengikuti lokasi eksekusi, bukan lokasi file.
- Server Component butuh cek session lalu lempar ke login: pakai
redirect(). - Server Action setelah login atau submit form berhasil: pakai
redirect()di akhir fungsi. - Client Component setelah klik tombol atau state berubah: pakai
useRouter(). - Middleware dan Route Handler sebelum response dibuat: pakai
NextResponse.redirect().
| Lokasi | API | Catatan |
|---|---|---|
| Server Component | redirect() |
Panggil sebelum JSX dikembalikan |
| Server Action | redirect() |
Jangan bungkus try catch |
| Client Component | useRouter() |
Butuh use client |
| Middleware | NextResponse.redirect() |
Butuh URL absolut |
Langkah Redirect di Server Component dan Server Action
redirect() menghentikan render dengan melempar error khusus Next.js. Panggil secara kondisional, bukan setelah render selesai.
- Import
redirectdanpermanentRedirectdarinext/navigation. - Panggil sebelum render saat kondisi terpenuhi, misalnya user belum login.
- Pakai
revalidatePath()di Server Action bila data halaman tujuan harus segar setelah redirect.
import { redirect, permanentRedirect } from 'next/navigation';
export default async function DashboardPage() {
const session = await getSession();
if (!session) redirect('/login');
return <p>Dashboard</p>;
}
export function OldDocsPage() {
permanentRedirect('/docs/baru');
}
'use server';
import { redirect } from 'next/navigation';
export async function loginAction(formData: FormData) {
const ok = await checkCredentials(formData);
if (!ok) return { error: 'Email atau kata sandi salah' };
redirect('/dashboard');
}
Langkah Redirect di Client Component dan Middleware
Navigasi client tidak melempar error. Ia berpindah halaman tanpa reload penuh dan bisa memilih menambah atau mengganti riwayat browser.
- Tandai file dengan
use clientdi baris pertama. - Ambil router lewat
useRouter(), lalu pakaipush(),replace(), ataurefresh(). - Untuk proteksi global seperti auth, tulis aturan di
middleware.tsdenganmatcher.
'use client';
import { useRouter } from 'next/navigation';
export default function BayarButton() {
const router = useRouter();
async function bayar() {
await prosesPembayaran();
router.replace('/checkout/sukses');
}
return <button onClick={bayar}>Bayar</button>;
}
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*'],
};
- Jangan menaruh
redirect()server di dalamtry catchkarena catch menelan sinyal redirect. - Jangan memanggil redirect setelah response Route Handler dikirim karena header sudah terkunci.
- Jangan memakai
useRouterdi Server Component karena hook hanya hidup di client.
FAQ
Kapan memakai redirect() dan useRouter().push?
Pakai redirect() untuk keputusan di server sebelum halaman dirender, pakai push() untuk aksi di browser seperti setelah klik.
Kenapa redirect di App Router tidak jalan?
Penyebab umum adalah redirect() dipanggil di Client Component, tertelan try catch, atau dipanggil setelah render dan response selesai.
Apakah middleware bisa membaca search params saat redirect?
Bisa, baca lewat request.nextUrl.searchParams lalu teruskan ke URL tujuan bila parameter itu perlu dipertahankan.