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

LaravelNext.js (App Router)
routes/web.phpStruktur folder app/ (file-based routing)
Controller + Blade viewServer Component di page.tsx
Layout Bladelayout.tsx
routes/api.phpRoute Handlers di route.ts
Form POST ke controllerServer Actions
Middlewaremiddleware.ts
Cache facadeCache 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.