Pernah bikin website pakai React atau Vue, terus pas dicek di PageSpeed Insight skornya cuma 40-an? Kayaknya hampir semua frontend developer pernah ngalamin ini. Kamu bikin landing page yang "cuma" teks dan gambar, tapi browser tetap download ratusan kilobyte JavaScript cuma buat render halaman statis.
Saya sendiri dulu kena masalah ini waktu bikin blog portfolio. Pakai Next.js, hasilnya bagus di dev, tapi pas production load-nya lambat banget. Lalu saya coba Astro dan langsung merasa bedanya. Halaman yang sama, load dalam 0.3 detik, skor PageSpeed 98. Kenapa? Karena Astro ngirim HTML murni ke browser. Zero JavaScript by default.
Astro itu Apa dan Kenapa Berbeda?
Astro adalah web framework modern yang fokus pada satu hal: ngirim sesedikit mungkin JavaScript ke browser. Berbeda dengan Next.js atau Nuxt yang hidup di client-side rendering, Astro default-nya static site generator (SSG). Artinya, setiap halaman di-build menjadi HTML statis saat deploy.
Tapi yang bikin Astro spesial bukan cuma SSG-nya. Konsep Islands Architecture adalah kuncinya. Bayangkan halaman website kamu seperti lautan HTML statis. Di tengah lautan itu, ada "pulau-pulau" kecil yang interaktif. Pulau-pulau ini adalah komponen JavaScript yang load secara terpisah dan independen.
<!-- Struktur Islands Architecture -->
<html>
<body>
<!-- Lautan HTML statis (zero JS) -->
<header>Logo dan Navigasi</header>
<main>
<article>Konten artikel blog...</article>
<!-- Pulau interaktif (JS load hanya untuk komponen ini) -->
<LikeButton client:visible />
<!-- Pulau lain, terpisah -->
<CommentForm client:idle />
</main>
<footer>Copyright 2026</footer>
</body>
</html>
Dengan pendekatan ini, browser hanya download JavaScript untuk komponen yang benar-benar butuh interaktivitas. Sisanya? HTML murni yang langsung render. Hasilnya: load super cepat, SEO friendly, dan user experience tetap bagus.
Setup Project Astro dari Nol
Mulai pakai Astro gampang banget. Kamu cuma butuh Node.js 18+ dan terminal. Jalankan command ini:
# Bikin project Astro baru
npm create astro@latest
# Astro bakal nanya beberapa hal:
# - Where? ./my-astro-blog
# - Template? Blog (pilih yang sesuai)
# - Install dependencies? Yes
# - TypeScript? Strict
# Masuk ke folder project
cd my-astro-blog
# Jalankan dev server
npm run dev
Dev server Astro jalan di localhost:4321. Perbedaan mencolok dibanding framework lain: dev server Astro sudah mendekati performance production. Tidak ada hot reload yang bikin browser berat. Tidak ada React DevTools yang makan memory. Cuma HTML yang dirender cepat.
Struktur Folder Astro
Astro punya struktur folder yang clean dan mudah dipahami. Ini layout dasarnya:
my-astro-blog/
|-- src/
| |-- components/
| | |-- Header.astro
| | |-- Footer.astro
| | |-- LikeButton.astro
| |-- layouts/
| | |-- BaseLayout.astro
| |-- pages/
| | |-- index.astro
| | |-- about.astro
| | |-- blog/
| | |-- [slug].astro
| |-- styles/
| |-- global.css
|-- public/
| |-- favicon.svg
| |-- images/
|-- astro.config.mjs
|-- package.json
Yang penting dipahami: folder src/pages/ otomatis jadi routing. File index.astro jadi homepage, about.astro jadi /about, dan blog/[slug].astro jadi dynamic route untuk blog posts. Mirip dengan Next.js Pages Router, tapi lebih simpel.
Membuat Komponen .astro Pertama
File .astro adalah format utama Astro. Setiap file punya dua bagian: component script (di dalam ---) dan markup (HTML/XHTML). Mari bikin komponen kartu artikel:
---
// src/components/ArticleCard.astro
// Bagian script: TypeScript/JavaScript di sini
interface Props {
title: string;
excerpt: string;
date: string;
slug: string;
}
const { title, excerpt, date, slug } = Astro.props;
// Format tanggal ke Indonesia
const formattedDate = new Date(date).toLocaleDateString('id-ID', {
day: 'numeric',
month: 'long',
year: 'numeric'
});
---
<article class="card">
<a href={`/blog/${slug}`}>
<h2>{title}</h2>
<p>{excerpt}</p>
<time datetime={date}>{formattedDate}</time>
</a>
</article>
<style>
.card {
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 1.5rem;
transition: box-shadow 0.2s;
}
.card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.card h2 {
margin-bottom: 0.5rem;
color: #1a202c;
}
.card time {
color: #718096;
font-size: 0.875rem;
}
</style>
Perhatikan: <style> di file .astro otomatis scoped. CSS di dalamnya cuma berlaku untuk komponen itu. Tidak ada class name collision. Tidak perlu CSS-in-JS. Astro handle semuanya saat build.
Content Collections - Manajemen Konten Type-Safe
Salah satu fitur terbaik Astro adalah Content Collections. Kalau kamu bikin blog, kamu biasanya simpan artikel di Markdown files. Tapi masalahnya Markdown tidak punya type safety. Kalau kamu lupa nulis title di frontmatter, error baru muncul saat render.
Content Collections solve ini dengan schema validation menggunakan Zod. Kamu definisikan struktur konten, dan Astro otomatis validasi setiap file Markdown:
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string().max(160), // SEO friendly
pubDate: z.coerce.date(),
tags: z.array(z.string()).default([]),
image: z.string().optional(),
draft: z.boolean().default(false),
}),
});
export const collections = {
blog: blogCollection,
};
Sekarang setiap artikel Markdown kamu akan divalidasi. Kalau kamu lupa description, Astro kasih error saat build, bukan saat user buka halaman. Contoh file Markdown:
---
title: "Belajar Astro dari Nol"
description: "Panduan lengkap Astro framework untuk pemula"
pubDate: 2026-10-02
tags: ["astro", "web-dev", "tutorial"]
image: "/images/astro-banner.png"
---
# Belajar Astro
Konten artikel dimulai di sini...
Dan untuk fetch semua artikel di halaman blog, kodenya cuma ini:
---
// src/pages/blog/index.astro
import { getCollection } from 'astro:content';
const posts = await getCollection('blog', ({ data }) => {
return data.draft === false; // Skip draft posts
});
// Urutkan berdasarkan tanggal terbaru
const sortedPosts = posts.sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
);
---
<section>
{sortedPosts.map((post) => (
<ArticleCard
title={post.data.title}
excerpt={post.data.description}
date={post.data.pubDate}
slug={post.slug}
/>
))}
</section>
Integrasi Framework Lain - Kekuatan Astro Islands
Inilah bagian yang bikin Astro unggul: kamu bisa pakai komponen React, Vue, Svelte, atau Solid di dalam project Astro yang sama. Tidak perlu pilih satu framework. Tidak perlu rewrite kode lama. Cuma install integration dan pakai.
# Install React integration
npx astro add react
# Install Vue integration
npx astro add vue
# Install Svelte integration
npx astro add svelte
# Install Tailwind CSS
npx astro add tailwind
Setelah install, kamu bisa import dan pakai komponen dari framework berbeda di file .astro yang sama:
---
// src/pages/index.astro
import ReactCounter from '../components/ReactCounter.jsx';
import VueNewsletter from '../components/VueNewsletter.vue';
import StaticContent from '../components/StaticContent.astro';
---
<html>
<body>
<!-- HTML statis, zero JS -->
<StaticContent />
<!-- React component sebagai island -->
<ReactCounter client:visible />
<!-- Vue component sebagai island -->
<VueNewsletter client:idle />
</body>
</html>
Directive client:visible berarti React Counter baru load JavaScript saat komponen masuk viewport. client:idle berarti load saat browser idle. Pilihan lain: client:load (load langsung), client:media (load pada screen size tertentu), dan client:only (skip SSR, render hanya di client).
Deploy Astro ke Production
Setelah selesai develop, saatnya deploy. Build project dengan:
# Build untuk production
npm run build
# Hasil build ada di dist/ folder
# Coba preview dulu
npm run preview
Ada beberapa opsi deploy yang populer untuk Astro:
- Vercel: Paling gampang. Push ke GitHub, connect ke Vercel, auto-deploy. Gratis untuk project kecil. Tambahkan adapter
@astrojs/vercelkalau butuh SSR. - Netlify: Alternatif Vercel dengan free tier yang generous. Pakai adapter
@astrojs/netlifyuntuk SSR support. - Cloudflare Pages: Gratis unlimited bandwidth. Cocok untuk traffic tingkat tinggi. Pakai adapter
@astrojs/cloudflare. - VPS Ubuntu: Kalau kamu mau full control. Build static, lalu serve dengan Nginx. Paling hemat untuk domain custom.
Untuk deploy ke VPS, caranya gampang:
# Di VPS: setup Nginx config
sudo nano /etc/nginx/sites-available/myblog
server {
listen 80;
server_name blog.example.com;
root /var/www/myblog/dist;
index index.html;
# Astro butuh fallback ke index.html untuk SPA-like routing
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets aggressively
location /_astro/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
sudo ln -s /etc/nginx/sites-available/myblog /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Astro otomatis generate hashed filenames untuk assets di /_astro/ folder, jadi cache busting berjalan otomatis tiap kali kamu deploy versi baru.
SEO yang Sudah Built-in
Astro lahir dengan SEO sebagai prioritas. Karena output-nya HTML statis, search engine bisa crawl semua konten tanpa eksekusi JavaScript. Tapi kamu tetap perlu setup meta tags dengan benar:
---
// src/layouts/BaseLayout.astro
interface Props {
title: string;
description: string;
image?: string;
}
const { title, description, image = '/og-default.png' } = Astro.props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
---
<html lang="id">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="canonical" href={canonicalURL} />
<title>{title}</title>
<meta name="description" content={description} />
<!-- Open Graph -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.site)} />
<meta property="og:url" content={canonicalURL} />
<meta property="og:type" content="website" />
<!-- Sitemap otomatis (butuh @astrojs/sitemap) -->
<link rel="sitemap" href="/sitemap-index.xml" />
</head>
<body>
<slot />
</body>
</html>
Tambahkan sitemap integration untuk auto-generate sitemap.xml:
npx astro add sitemap
// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://blog.example.com',
integrations: [sitemap()],
});
Kapan Pakai Astro dan Kapan Tidak?
Astro bukan silver bullet. Ada kondisi di mana Astro sempurna, dan ada kondisi di mana framework lain lebih cocok.
Pakai Astro kalau:
- Bikin blog atau content-heavy website (dokumentasi, portfolio, marketing site)
- Performance dan PageSpeed score adalah prioritas nomor satu
- Mayoritas halaman statis dengan sedikit interaktivitas
- Mau pakai multiple framework tanpa rewrite
- Butuh SEO yang maksimal dari hari pertama
Skip Astro kalau:
- Bikin dashboard admin yang full interaktif (pakai Next.js atau Nuxt aja)
- Butuh real-time data dengan WebSocket terus-menerus
- Aplikasi yang 90% client-side rendering (SPA murni)
- Team kamu sudah invest heavy di React/Vue ecosystem dan tidak butuh static
Kesimpulan
Astro mengubah cara saya mikir tentang web development. Tidak semua halaman butuh React di client-side. Tidak semua interaksi butuh SPA. Kadang HTML murni plus sedikit JavaScript di tempat yang tepat adalah jawaban terbaik.
Kalau kamu bikin blog, documentation site, portfolio, atau landing page, Astro adalah pilihan yang sulit dikalahkan. Performance-nya luar biasa, developer experience-nya enak, dan fleksibilitasnya pakai komponen dari framework apapun bikin kamu tidak terkunci di satu ekosistem.
Penasaran? Coba bikin satu halaman dengan Astro hari ini. Pasang di Vercel atau Cloudflare Pages gratis. Lalu compare PageSpeed score-nya dengan project React/Vue kamu sebelumnya. Saya jamin kamu akan terkejut dengan bedanya.
Sudah pernah coba Astro? Atau masih setia dengan Next.js/Nuxt? Share pengalaman kamu di kolom komentar, saya mau dengar perspektif dari sisi lain.