Next.js adalah framework React full-stack: satu proyek berisi halaman, logika server, dan endpoint API. Bagi backend developer, kunci memahaminya adalah mengetahui di mana setiap baris kode berjalan. Di App Router, komponen secara default berjalan di server (Server Components), sehingga kamu bisa mengakses database atau API langsung dari komponen, lalu hanya bagian interaktif yang dikirim ke browser.
Padanan Konsep untuk Backend Developer Laravel
| Laravel | Next.js (App Router) |
|---|---|
routes/web.php | Struktur folder app/ (file-based routing) |
| Controller + Blade view | Server Component di page.tsx |
| Layout Blade | layout.tsx |
routes/api.php | Route Handlers di route.ts |
| Form POST ke controller | Server Actions |
| Middleware | middleware.ts |
| Cache facade | Cache data dan revalidasi bawaan |
.env dan config() | process.env; variabel publik diawali NEXT_PUBLIC_ |
Routing Berbasis Folder
app/
layout.tsx # layout utama
page.tsx # /
produk/
page.tsx # /produk
[slug]/
page.tsx # /produk/kaos-polos
api/
pesanan/
route.ts # /api/pesanan
Server Components: Ambil Data Langsung
// app/produk/[slug]/page.tsx
export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const response = await fetch(`${process.env.API_URL}/products/${slug}`, {
next: { revalidate: 300 }, // cache 5 menit
});
if (!response.ok) notFound();
const product = await response.json();
return (
<main>
<h1>{product.name}</h1>
<AddToCartButton productId={product.id} />
</main>
);
}
Kode di atas berjalan di server. Token API dan URL internal tidak pernah sampai ke browser. Komponen yang butuh interaksi, seperti tombol keranjang, ditandai 'use client':
'use client';
export function AddToCartButton({ productId }: { productId: number }) {
const [loading, setLoading] = useState(false);
// ...
}
Cara Halaman Dirender
- Statis: dirender saat build atau pertama kali diakses, lalu disajikan dari cache. Cocok untuk halaman konten.
- Dinamis (SSR per request): dirender setiap request, misalnya karena membaca cookie atau header. Cocok untuk halaman yang dipersonalisasi.
- Revalidasi: halaman statis diperbarui berkala (
revalidate) atau saat data berubah (revalidatePath,revalidateTag).
Aturan caching Next.js berubah beberapa kali di versi terakhir. Selalu cek dokumentasi versi yang kamu pakai, dan uji apakah halaman benar-benar statis atau dinamis lewat output next build.
Route Handlers untuk API
// app/api/pesanan/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const body = await request.json();
if (!body.productId || body.qty < 1) {
return NextResponse.json({ message: 'Data tidak valid' }, { status: 422 });
}
const order = await createOrder(body);
return NextResponse.json(order, { status: 201 });
}
Server Actions untuk Form
// app/kontak/actions.ts
'use server';
export async function sendMessage(formData: FormData) {
const email = String(formData.get('email') ?? '');
if (!email.includes('@')) {
return { error: 'Email tidak valid' };
}
await saveMessage({ email, message: String(formData.get('message') ?? '') });
return { success: true };
}
Server Action seperti endpoint POST publik. Validasi input dan cek otorisasi di dalamnya, sama seperti di controller Laravel.
Next.js atau Laravel?
- Next.js sebagai frontend, Laravel sebagai API: kombinasi umum untuk tim yang ingin UI React modern dengan backend yang matang untuk queue, autentikasi, dan admin.
- Laravel dengan Inertia dan React: kalau ingin satu aplikasi tanpa API terpisah, tapi tetap memakai komponen React.
- Next.js full-stack: cocok untuk aplikasi yang logika backend-nya ringan atau memakai layanan terkelola untuk database dan autentikasi.
Kesalahan yang Sering Terjadi
- Menaruh
'use client'di layout teratas, sehingga seluruh aplikasi jadi komponen klien dan manfaat Server Components hilang. - Membocorkan rahasia dengan memberi awalan
NEXT_PUBLIC_pada variabel yang seharusnya rahasia. - Bingung data basi karena tidak paham cache. Tentukan secara eksplisit apakah sebuah fetch boleh di-cache.
- Server Action tanpa otorisasi, karena dianggap fungsi internal padahal bisa dipanggil dari luar.
Langkah Berikutnya
Next.js paling nyaman dipakai dengan TypeScript; dasarnya ada di TypeScript untuk Laravel developer. Untuk styling cepat, banyak proyek Next.js memakai Tailwind CSS v4.