Cara Deploy Astro ke Cloudflare
Panduan deploy situs Astro ke Cloudflare Workers untuk mode statis maupun SSR: konfigurasi wrangler, deploy otomatis dari Git, dan cara memilih di antara keduanya.
Astro punya dua mode keluaran, dan langkah deploy-nya berbeda tergantung mode yang kamu pakai. Kebanyakan tutorial melewatkan bagian ini, jadi orang mengikuti langkah untuk mode SSR padahal situsnya statis — lalu bingung kenapa ada berkas _worker.js yang tidak diminta.
Panduan ini memisahkan keduanya dengan jelas. Mulai dari menentukan mode mana yang kamu butuh.
Statis atau SSR? Tentukan dulu
Secara bawaan Astro membangun situs statis: semua halaman dirender jadi HTML saat build. Ini mode yang benar untuk blog, dokumentasi, portofolio, landing page — mayoritas situs Astro.
Kamu baru butuh SSR kalau halaman harus dirender per permintaan: ada login, isi halaman berbeda tiap pengguna, atau data yang berubah tiap detik.
Situs statis lebih cepat, lebih murah, dan lebih sedikit yang bisa rusak. Astro juga mendukung mode hibrida — mayoritas halaman statis, hanya sebagian yang dirender per permintaan — jadi kamu tidak perlu memutuskan untuk seluruh situs sekaligus.
Yang perlu disiapkan
- Node.js 20 atau lebih baru — cek dengan
node -v. - Akun Cloudflare, paket gratis cukup.
- Project Astro yang jalan dengan
npm run dev. Belum ada? Bikin dengannpm create astro@latest.
Jalur A: Situs statis
Ini jalur yang paling mungkin kamu butuhkan, dan yang paling sederhana — tidak perlu adapter sama sekali.
1. Pastikan hasil build benar
npm run build
Astro akan menulis hasilnya ke folder dist/. Isinya harus berupa berkas HTML, CSS, dan JS biasa. Kalau di dalamnya ada folder _worker.js, berarti project-mu sudah dikonfigurasi SSR — lompat ke Jalur B.
2. Isi baseURL situs
Buka astro.config.mjs dan isi site dengan alamat final situsmu. Ini dipakai Astro untuk membuat sitemap dan URL kanonik:
import { defineConfig } from 'astro/config';
export default defineConfig({
site: 'https://situsku.com',
});
3. Pasang Wrangler dan konfigurasinya
npm install --save-dev wrangler
Bikin wrangler.jsonc di root project:
// wrangler.jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "situs-astro",
"compatibility_date": "2026-03-01",
"assets": {
"directory": "./dist"
}
}
Perhatikan yang tidak ada di situ: tidak ada main, tidak ada nodejs_compat. Situs statis murni tidak menjalankan kode server, jadi tidak perlu keduanya.
4. Deploy
npx wrangler login
npm run build
npx wrangler deploy
Keluarannya:
Uploaded 47 files (2.31 sec)
Deployed situs-astro triggers (0.94 sec)
https://situs-astro.akun-kamu.workers.dev
Selesai. Situsmu sudah tersaji dari jaringan edge Cloudflare.
Jalur B: SSR
Kalau kamu butuh render per permintaan, tambahkan adapter Cloudflare.
1. Pasang adapter
npx astro add cloudflare
Perintah ini memasang @astrojs/cloudflare dan menyunting astro.config.mjs secara otomatis. Hasilnya kira-kira:
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
site: 'https://situsku.com',
output: 'server',
adapter: cloudflare(),
});
2. Konfigurasi Wrangler untuk SSR
Berbeda dari jalur statis — di sini kita perlu menunjuk berkas Worker-nya:
// wrangler.jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "situs-astro",
"main": "./dist/_worker.js/index.js",
"compatibility_date": "2026-03-01",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": "./dist",
"binding": "ASSETS"
}
}
Tiga tambahan dibanding jalur statis: main menunjuk berkas Worker hasil build, nodejs_compat memberi akses API Node.js, dan assets.binding supaya Worker bisa menyajikan berkas statis.
3. Mode hibrida
Kalau hanya sebagian halaman yang butuh SSR, tetap pakai output: 'server', lalu tandai halaman yang boleh statis dengan menambahkan baris ini di bagian frontmatter halaman tersebut:
---
export const prerender = true;
---
Halaman itu akan dirender saat build, sisanya per permintaan. Ini cara paling hemat: hanya halaman yang benar-benar dinamis yang membebani Worker.
Deploy otomatis tiap push
Deploy manual cocok untuk mencoba. Untuk kerja sehari-hari, hubungkan Git.
Lewat dashboard
Di dashboard Cloudflare, buka Workers & Pages → Create → hubungkan repositori. Isi setelan build:
| Kolom | Isi |
|---|---|
| Build command | npm run build |
| Output directory | dist |
| Node version | 20 atau lebih baru |
Lewat GitHub Actions
# .github/workflows/deploy.yml
name: Deploy Astro ke Cloudflare
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
Buat API token lewat My Profile → API Tokens di dashboard Cloudflare dengan template Edit Cloudflare Workers, lalu simpan token dan Account ID sebagai repository secret di GitHub.
Pasang domain sendiri
Buka Worker kamu di dashboard → Settings → Domains & Routes → Add → Custom domain. Kalau domainnya sudah dikelola Cloudflare, DNS dan sertifikat SSL selesai otomatis dalam hitungan menit.
Setelah domain aktif, jangan lupa perbarui site di astro.config.mjs supaya sitemap dan URL kanonik menunjuk ke alamat yang benar. Detail soal DNS dan SSL ada di panduan custom domain dan SSL.
Masalah yang sering muncul
Gambar dan CSS 404
Periksa assets.directory di wrangler.jsonc — harus ./dist, bukan ./dist/client atau folder lain. Kalau kamu menaruh situs di subfolder, isi juga base di astro.config.mjs.
Error "nodejs_compat is not enabled"
Ini hanya terjadi di jalur SSR. Pastikan baris compatibility_flags ada dan compatibility_date minimal 2024-09-23.
Halaman selalu statis padahal sudah pakai adapter
Cek apakah masih ada output: 'static' tersisa di astro.config.mjs. Nilai itu menimpa adapter, dan semua halaman tetap dirender saat build.
Integrasi gagal saat build di server
Beberapa integrasi Astro — terutama yang memproses gambar — butuh dependensi sistem yang tidak selalu ada di lingkungan build. Kalau @astrojs/image atau sejenisnya gagal, coba pindah ke komponen <Image /> bawaan Astro yang tidak butuh binary tambahan.
Environment variable tidak terbaca di browser
Astro hanya mengekspos variabel yang diawali PUBLIC_ ke kode sisi klien. Tanpa prefiks itu, nilainya hanya tersedia saat build dan di sisi server.
Memastikan deploy-nya benar
Setelah deploy pertama, tiga pemeriksaan ini menangkap hampir semua masalah:
- Buka DevTools lalu tab Network, dan muat ulang. Semua berkas harus 200. Aset yang 404 hampir selalu berarti
assets.directorysalah. - Cek halaman mana yang statis. Halaman yang di-prerender mengembalikan header
cf-cache-status. Yang dilayani Worker tidak. - Buka
/sitemap-index.xmlkalau kamu memakai integrasi sitemap. URL di dalamnya harus memakai domain final, bukanlocalhost— kalau salah, berartisitedi konfigurasi belum diisi.
curl -sSI https://situs-astro.workers.dev/ | grep -i "cf-cache-status"
Optimasi gambar
Astro punya komponen <Image /> bawaan yang mengubah ukuran dan format gambar saat build. Untuk situs statis, ini berjalan di lingkungan build dan hasilnya ikut ter-deploy sebagai berkas biasa — tidak ada biaya runtime sama sekali.
---
import { Image } from 'astro:assets';
import foto from '../assets/foto.jpg';
---
<Image src={foto} alt="Keterangan gambar" width={800} />
Untuk mode SSR, pemrosesan gambar tidak jalan di Worker karena runtime-nya tidak menyediakan library yang dibutuhkan. Dua jalan keluarnya: pakai <Image /> hanya di halaman yang di-prerender, atau serahkan ke layanan gambar eksternal.
Batas paket gratis Cloudflare Workers
| Hal | Batas |
|---|---|
| Permintaan aset statis | Tidak dibatasi |
| Pemanggilan Worker | 100.000 per hari |
| Waktu CPU | 10 ms per pemanggilan |
| Ukuran Worker | 3 MB setelah gzip |
Perhatikan baris pertama — itu yang membuat jalur statis jauh lebih murah. Situs statis murni tidak memanggil Worker sama sekali, jadi batas 100.000 per hari tidak pernah tersentuh berapa pun ramainya situsmu.
Ini alasan paling praktis untuk mem-prerender sebanyak mungkin halaman, dan menyisakan SSR hanya untuk yang benar-benar butuh.
Ringkasan
| Statis | SSR | |
|---|---|---|
| Adapter | Tidak perlu | @astrojs/cloudflare |
output | bawaan (statis) | 'server' |
main di wrangler | Tidak ada | ./dist/_worker.js/index.js |
nodejs_compat | Tidak perlu | Wajib |
assets.binding | Tidak perlu | ASSETS |
Kalau deploy-mu gagal dengan pesan yang tidak dibahas di sini, cek 15 error deploy paling umum. Untuk Next.js di Cloudflare, langkahnya berbeda cukup jauh — ada di panduan Next.js ke Cloudflare.
Untuk gambaran menyeluruh soal deploy, mulai dari panduan lengkap deploy website. Kalau kamu masih menimbang platform, lihat panduan memilih hosting statis.