Cloudflare
Overzicht
Section titled “Overzicht”Beam draait 100% op Cloudflare — hosting, API runtime, media opslag, image processing en custom domains. Geen AWS, geen Vercel, geen VPS.
| Service | Gebruik |
|---|---|
| Pages | Dashboard + public site hosting |
| Workers | API + router worker + cron triggers |
| R2 | Media opslag (originals + thumbnails) |
| Image Resizing | Blur placeholders, thumbnails, responsive images |
| Custom Domains API | Klant-domeinen koppelen |
| Cache API | Pagina cache + purge bij publicatie |
Twee Pages-projecten:
| Project | Domein | App |
|---|---|---|
beam-dashboard | app.builtwithbeam.com | Vite SPA (dashboard) |
beam-public-site | Klant-domeinen | Astro SSR (publieke sites) |
Deploy via GitHub Actions (wrangler pages deploy). Dashboard build uploadt ook Sentry source maps.
Workers
Section titled “Workers”Twee Workers:
API Worker (beam-api)
Section titled “API Worker (beam-api)”Hono 4.7 op api.builtwithbeam.com. Alle CRUD operaties, media uploads, team management.
Cron triggers:
*/5 * * * *— Domain status polling (pending → active/error)0 3 * * *— Media cleanup (orphaned bestanden, max 100 per run)
Router Worker (beam-router)
Section titled “Router Worker (beam-router)”Routeert *.builtwithbeam.com traffic:
| Patroon | Destination |
|---|---|
app.builtwithbeam.com, www.builtwithbeam.com | Dashboard Pages project |
docs.builtwithbeam.com | Docs Pages project |
| Alle andere subdomains | Public site Pages project |
De worker set Host naar het origin en X-Beam-Host naar het oorspronkelijke hostname.
R2 (Object Storage)
Section titled “R2 (Object Storage)”Bucket: MEDIA_BUCKET (binding in wrangler.toml)
{siteId}/ originals/{fileId}.{ext} # Origineel bestand thumbnails/{fileId}.webp # 400px WebP thumbnail- Direct binding (geen S3 API overhead)
- Geen egress kosten
- Cleanup cron verwijdert orphaned bestanden dagelijks
Image Resizing
Section titled “Image Resizing”Gebruikt voor drie doelen:
| Doel | Formaat | Breedte |
|---|---|---|
| Blur placeholder (LQIP) | Base64 data URL | 20px |
| Thumbnail | WebP | 400px |
| Responsive afbeeldingen | Origineel formaat | 640, 750, 828, 1080, 1200, 1920, 2048, 3840px |
URL patroon: https://domain.com/cdn-cgi/image/width=W,quality=Q,format=auto/path
Publieke site gebruikt srcSet met alle breedtes voor optimale afbeeldingen per viewport.
Custom Domains
Section titled “Custom Domains”Flow:
Gebruiker voert domein in → POST /domains/connect → Validatie: DNS regex, blocked list, max 5 per site → CF Pages Custom Domain aanmaken via CF API → Record in site_domains (status: pending) → Cron */5 min: poll CF API → DNS geconfigureerd? → status: active → 48 uur geen respons? → status: errorAPI: CF Pages Custom Domains API (niet de legacy Custom Hostnames API).
Limieten:
- Max 5 domeinen per site
- Eerste domein wordt automatisch primary
- Verwijderen: CF API cleanup + DB cleanup + next domain promoted
Strategie: s-maxage=300, stale-while-revalidate=600 op publieke pagina’s.
Purge: POST /cache/purge — max 30 URLs per request. Fire-and-forget bij pagina save.
Headers: Vary: Host voor correcte CDN caching per klant-domein.
Environment Variables
Section titled “Environment Variables”| Variabele | Type | Doel |
|---|---|---|
CF_ACCOUNT_ID | Var | Account identifier |
CF_ZONE_ID | Var | Zone identifier |
CF_API_TOKEN | Secret | API token (domains, cache) |
DASHBOARD_ORIGIN | Var | CORS allowed origin |
MEDIA_BUCKET | R2 binding | Object storage |
Kosten
Section titled “Kosten”Beam valt ruim binnen de gratis tiers:
| Service | Free tier | Beam gebruik |
|---|---|---|
| Workers | 100K req/dag | Laag |
| Pages | 500 builds/maand | ~30 deploys/maand |
| R2 | 10 GB opslag, 10M reads | Groeit per site |
| Image Resizing | Betaald ($0.50/1000) | Per afbeelding |
Troubleshooting
Section titled “Troubleshooting”| Probleem | Oorzaak | Oplossing |
|---|---|---|
| Custom domain blijft “pending” | DNS niet geconfigureerd | CNAME naar Pages project instellen |
| Cache niet geïnvalideerd | Purge mislukt of Vary: Host mist | Check POST /cache/purge response |
| R2 upload faalt | Binding niet geconfigureerd | Check MEDIA_BUCKET in wrangler.toml |
| Image Resizing 403 | Feature niet enabled op zone | Enable in CF dashboard > Speed > Optimization |