Tutorial

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.

Kalau ragu, pilih statis

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 dengan npm 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 & PagesCreate → hubungkan repositori. Isi setelan build:

KolomIsi
Build commandnpm run build
Output directorydist
Node version20 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 → SettingsDomains & RoutesAddCustom 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:

  1. Buka DevTools lalu tab Network, dan muat ulang. Semua berkas harus 200. Aset yang 404 hampir selalu berarti assets.directory salah.
  2. Cek halaman mana yang statis. Halaman yang di-prerender mengembalikan header cf-cache-status. Yang dilayani Worker tidak.
  3. Buka /sitemap-index.xml kalau kamu memakai integrasi sitemap. URL di dalamnya harus memakai domain final, bukan localhost — kalau salah, berarti site di 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

HalBatas
Permintaan aset statisTidak dibatasi
Pemanggilan Worker100.000 per hari
Waktu CPU10 ms per pemanggilan
Ukuran Worker3 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

StatisSSR
AdapterTidak perlu@astrojs/cloudflare
outputbawaan (statis)'server'
main di wranglerTidak ada./dist/_worker.js/index.js
nodejs_compatTidak perluWajib
assets.bindingTidak perluASSETS

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.