SSR vs SSG dengan Claude Code: strategi rendering Next.js dan Astro
Bandingkan SSR, SSG, ISR, dan static export di Next.js/Astro dengan Claude Code, contoh jalan, dan perintah verifikasi.
Samakan istilah dulu
Memilih SSR atau SSG bukan sekadar memilih yang paling cepat. SSR berarti server-side rendering: server membuat HTML saat request datang. SSG berarti static site generation: HTML dibuat saat build, lalu disajikan lewat CDN atau hosting statis. ISR, Incremental Static Regeneration, berada di tengah: halaman disajikan seperti statis, tetapi bisa dibuat ulang berdasarkan waktu atau event revalidasi.
Kesalahan umum di Next.js App Router adalah mengira Server Component selalu berarti SSR setiap request. Tidak begitu. Dalam dokumentasi resmi Dynamic Route Segments, contoh TypeScript memperlakukan params sebagai Promise. Jika Anda perlu membuat render menunggu request sungguhan, API saat ini adalah connection.
Jika Anda hanya meminta Claude Code “buat halaman ini lebih cepat”, ia bisa terlalu agresif membuat halaman statis dan membekukan stok, hasil pencarian, atau UI anggota. Jika semua dibuat SSR, TTFB dan biaya server bisa naik. Cara yang lebih aman adalah meminta matriks route dulu: kesegaran data, personalisasi, frekuensi update, dampak monetisasi, dan perintah verifikasi.
Perbandingan dan kasus nyata
| Pertanyaan | SSG | ISR | SSR |
|---|---|---|---|
| Kapan HTML dibuat | Saat build | Build dan revalidasi | Saat request |
| Cocok untuk | Artikel, docs, landing page | Produk, kategori, berita | Dashboard, search, cart |
| Kesegaran data | Snapshot build | Berdasarkan waktu atau event | Hampir terbaru |
| Biaya penyajian | Rendah | Sedang | Sering lebih tinggi |
| Risiko umum | Build lama, konten basi | Respons lama sesaat | Lambat tanpa cache |
Kasus 1 adalah blog atau dokumentasi. Jika body, OGP, internal link, dan CTA stabil saat publish, SSG paling bersih. Rebuild ketika artikel berubah. Jika juga ingin mengurangi JavaScript, baca code splitting dengan Claude Code.
Kasus 2 adalah halaman produk ecommerce. Harga, stok, dan urutan kategori bisa berubah tiap beberapa menit, tetapi pengunjung tetap butuh respons cepat. ISR cocok. Panduan resmi Next.js ISR menjelaskan bahwa ISR berjalan dengan Node.js runtime dan tidak didukung oleh static export.
Kasus 3 adalah dashboard akun. Cookies, permission, status billing, notifikasi, dan rekomendasi privat bergantung pada request. Perlakukan sebagai SSR dan atur cache header dengan jelas. Jika tim mempertimbangkan edge untuk route dinamis, baca edge computing dengan Claude Code setelah menentukan data mana yang aman didekatkan ke pengguna.
Contoh SSR Next.js
Contoh ini bisa ditempel ke proyek Next.js App Router. Ia memakai dummyjson.com, jadi tidak perlu API key. connection() dan cache: "no-store" membuat perilaku request-time jelas saat review.
// app/products/[id]/page.tsx
import { notFound } from "next/navigation";
import { connection } from "next/server";
type Product = {
id: number;
title: string;
price: number;
stock: number;
updatedAt: string;
};
async function getProduct(id: string): Promise<Product | null> {
await connection();
const res = await fetch(`https://dummyjson.com/products/${id}`, {
cache: "no-store",
});
if (res.status === 404) return null;
if (!res.ok) throw new Error(`Failed to load product: ${res.status}`);
const data = (await res.json()) as {
id: number;
title: string;
price: number;
stock: number;
meta?: { updatedAt?: string };
};
return {
id: data.id,
title: data.title,
price: data.price,
stock: data.stock,
updatedAt: data.meta?.updatedAt ?? new Date().toISOString(),
};
}
export default async function ProductPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const product = await getProduct(id);
if (!product) notFound();
return (
<main>
<h1>{product.title}</h1>
<p>Price: ${product.price.toLocaleString("en-US")}</p>
<p>Stock: {product.stock}</p>
<p>Updated: {new Date(product.updatedAt).toLocaleString("id-ID")}</p>
</main>
);
}
Jebakan utama adalah memasukkan cookies() atau headers() ke layout bersama karena terasa praktis. API berbasis request bisa membuat banyak route menjadi dinamis. Jika layout itu membungkus artikel, halaman yang seharusnya cukup SSG ikut terdampak. Minta Claude Code membuat daftar route terdampak sebelum menerima patch.
Pisahkan SSG, ISR, dan static export
SSG dan ISR bisa terasa sama bagi pengunjung, tetapi cara operasinya berbeda. SSG diperbarui saat build. ISR diperbarui setelah jendela waktu atau event. Static export memakai output: "export" untuk membuat folder out, yang bisa disajikan tanpa server Node.js. Panduan resmi Static Exports menjelaskan bahwa next build dapat membuat satu HTML per route untuk hosting statis.
// app/catalog/[id]/page.tsx
import { notFound } from "next/navigation";
export const revalidate = 3600;
type Product = {
id: number;
title: string;
description: string;
};
export async function generateStaticParams() {
return ["1", "2", "3"].map((id) => ({ id }));
}
async function getProduct(id: string): Promise<Product | null> {
const res = await fetch(`https://dummyjson.com/products/${id}`, {
next: { revalidate: 3600, tags: [`product:${id}`] },
});
if (res.status === 404) return null;
if (!res.ok) throw new Error(`Failed to load product: ${res.status}`);
return (await res.json()) as Product;
}
export default async function CatalogPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const product = await getProduct(id);
if (!product) notFound();
return (
<article>
<h1>{product.title}</h1>
<p>{product.description}</p>
</article>
);
}
// next.config.mjs
const nextConfig = {
output: "export",
images: {
unoptimized: true,
},
};
export default nextConfig;
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"export:check": "next build && npx serve out"
}
}
Jangan anggap static export dan ISR bisa dipakai bergantian. Static export cocok untuk hosting statis. Jika route perlu cookies, on-demand revalidation, Server Functions, atau SSR sungguhan, Anda perlu server runtime. Sebelum Claude Code menulis kode, beri tahu target deploy: Cloudflare Pages statis, container Node, Vercel, Netlify, atau platform lain.
Astro statis dan on-demand
Astro default-nya condong ke static generation. Dokumentasi resmi Astro on-demand rendering menyebut bahwa pages, routes, dan API endpoints diprerender saat build secara default. Setelah menambahkan server adapter, route tertentu bisa memakai export const prerender = false untuk render saat request.
---
// src/pages/docs/[slug].astro
export async function getStaticPaths() {
const docs = [
{ slug: "ssr", title: "SSR guide" },
{ slug: "ssg", title: "SSG guide" },
];
return docs.map((doc) => ({
params: { slug: doc.slug },
props: { doc },
}));
}
const { doc } = Astro.props;
---
<html lang="id">
<body>
<article>
<h1>{doc.title}</h1>
<p>This page was generated at build time.</p>
</article>
</body>
</html>
---
// src/pages/account.astro
export const prerender = false;
const session = Astro.cookies.get("session")?.value;
const name = session ? "Masa" : "Guest";
Astro.response.headers.set("Cache-Control", "private, no-store");
---
<html lang="id">
<body>
<h1>Account</h1>
<p>Hello, {name}.</p>
</body>
</html>
Kesalahan umum di Astro adalah lupa adapter. Halaman bisa terlihat benar secara lokal, tetapi on-demand rendering di production membutuhkan server runtime. Minta Claude Code memeriksa astro.config.mjs, platform deploy, dan setiap override prerender.
Perintah verifikasi dan prompt
Strategi rendering tidak cukup diverifikasi dengan membaca kode. Periksa build output, response header, cache log, dan metrik seperti TTFB dan LCP. Untuk ISR, dokumentasi Next.js juga menyarankan pengujian perilaku production dengan next build dan next start.
# Next.js: production behavior
npm run build
npm run start
# In another terminal
curl -I http://localhost:3000/catalog/1
curl -I http://localhost:3000/products/1
# ISR cache debugging
NEXT_PRIVATE_DEBUG_CACHE=1 npm run start
# Astro
npm run build
npm run preview
Prompt untuk Claude Code sebaiknya meminta catatan keputusan, bukan hanya kode:
Goal: classify every route in a Next.js/Astro site as SSR, SSG, ISR, or static export.
Inspect:
- app/ or src/pages/ routes
- cookies(), headers(), searchParams, connection(), cache: "no-store"
- generateStaticParams(), revalidate, output: "export", Astro prerender
- monetization pages, member pages, articles, product pages, and search pages
Constraints:
- Do not break SEO metadata or internal links
- Keep npm run build passing before and after
- Return a table with the chosen strategy, reason, touched files, and verification command
Jebakan konkret
Pertama, memasukkan konten spesifik pengguna ke body artikel statis. Nama anggota, rekomendasi privat, dan harga tersembunyi tidak boleh masuk ke HTML SSG. Biarkan artikel statis dan pindahkan personalisasi ke client component atau bagian dinamis yang jelas.
Kedua, mengatur interval ISR terlalu pendek. revalidate = 1 sering hanya mengembalikan biaya ke server. Jika perlu update presisi, gunakan on-demand revalidation. Jika perlu real-time, gunakan SSR.
Ketiga, memilih static export lalu menambahkan fitur server. Auth, UI berbasis cookie, Server Route Handlers, dan ISR butuh runtime. Hosting statis sangat berguna, tetapi bukan pengganti server.
Keempat, menerima proposal Claude Code hanya karena tampak paling cepat. Untuk situs konten yang dimonetisasi, performa hanya salah satu bagian. OGP, structured data, internal link, posisi iklan, tracking CTA, LCP, dan CLS juga penting. Setelah memilih strategi, lanjutkan dengan optimasi performa Claude Code.
Rekomendasi dengan monetisasi
Untuk bisnis konten seperti ClaudeCodeLab, gunakan SSG sebagai default untuk artikel, tutorial, perbandingan, dan halaman awal funnel. Gunakan ISR untuk katalog produk, kategori, dan permukaan yang bisa menerima konten sedikit lama. Gunakan SSR untuk akun, search, cart, konteks checkout, dan semua route yang memakai data privat dari request.
Untuk memulai workflow praktis, ambil cheatsheet Claude Code gratis. Untuk template dan paket implementasi, lihat halaman produk. Jika tim perlu menyatukan strategi route, permissions, code review, analytics, dan training rollout, mulai dari Claude Code training and consultation.
Hasil yang saya verifikasi
Untuk pembaruan ini, saya memeriksa dokumentasi resmi Next.js Dynamic Route Segments, connection, ISR, Static Exports, Astro on-demand rendering, dan Claude Code overview. Dalam workflow konten Masa, pembagian paling stabil adalah SSG untuk artikel, ISR untuk produk dan kategori, SSR untuk akun dan pencarian. Langkah Claude Code yang paling berguna adalah meminta route classification table sebelum perubahan kode. Tabel itu menemukan penggunaan cookie yang tidak sengaja di halaman statis lebih awal dan membuat setiap route punya alasan serta command verifikasi.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.