Frontend Deployment
Deploy your frontend directly from Butterbase. Build your app locally, zip the output, upload it, and deploy to a live URL powered by Cloudflare Pages.
Frontend deployments are served globally and aren’t tied to a single region — your static assets reach users fast no matter where your app’s backend lives.
How it works
Section titled “How it works”- Call
create_frontend_deploymentto get a deployment ID and upload URL - Upload your built frontend as a zip file
- Call
start_frontend_deploymentto trigger the deployment - Your site goes live at a
.pages.devURL
Supported frameworks
Section titled “Supported frameworks”| Framework | Value | Notes |
|---|---|---|
| React (Vite) | react-vite | dist/ folder from npm run build |
| Next.js (static) | nextjs-static | out/ folder from next build && next export |
| Static HTML | static | Any plain HTML/CSS/JS files |
| Other | other | Any framework that produces static output |
Deploying via MCP
Section titled “Deploying via MCP”Step 1: Create deployment
create_frontend_deployment({ app_id: "app_abc123", framework: "react-vite" })Step 2: Upload your zip
curl -X PUT "{uploadUrl}" \ -H "Content-Type: application/zip" \ --data-binary @frontend.zipStep 3: Start deployment
start_frontend_deployment({ app_id: "app_abc123", deployment_id: "uuid-1234" })Deployment statuses
Section titled “Deployment statuses”| Status | Meaning |
|---|---|
WAITING | Created, awaiting zip upload |
UPLOADING | Files are being processed |
BUILDING | Deployment is being built |
READY | Succeeded — URL is assigned |
ERROR | Failed — check the error message |
CANCELED | Deployment was canceled |
Creating the zip file correctly
Section titled “Creating the zip file correctly”Recommended: Node.js archiver
Section titled “Recommended: Node.js archiver”npm install archiver --save-devconst fs = require('fs');const path = require('path');const archiver = require('archiver');
const output = fs.createWriteStream(path.join(__dirname, 'frontend.zip'));const archive = archiver('zip', { zlib: { level: 9 } });
output.on('close', () => { console.log(`frontend.zip created (${archive.pointer()} bytes)`);});
archive.on('error', (err) => { throw err; });archive.pipe(output);archive.directory('dist/', false);archive.finalize();Alternative: Git Bash / WSL
Section titled “Alternative: Git Bash / WSL”cd dist && zip -r ../frontend.zip .Environment variables
Section titled “Environment variables”Set environment variables for frontend builds:
PUT /v1/{app_id}/frontend/env
{ "VITE_API_URL": "https://api.butterbase.ai/v1/app_abc123", "VITE_APP_NAME": "My App"}Framework-specific prefixes:
- Vite:
VITE_(e.g.,VITE_API_URL) - Next.js:
NEXT_PUBLIC_(e.g.,NEXT_PUBLIC_API_URL) - Create React App:
REACT_APP_(e.g.,REACT_APP_API_URL)
SPA routing
Section titled “SPA routing”For single-page app frameworks, a _redirects file is automatically injected so all routes serve index.html. Client-side routing works out of the box. If your zip includes a custom _redirects, it is preserved.
Redeployment
Section titled “Redeployment”Each deployment is kept independently until you hit your plan’s deployment limit. Delete old deployments you no longer need.
Custom domains
Section titled “Custom domains”Point your own hostname at this deployment — app.example.com instead of *.pages.dev — with SSL issued and renewed automatically. Requires the Launch plan or above.
butterbase domains add app.example.combutterbase domains status <domain-id>Full setup, DNS records, validation methods, apex handling, and troubleshooting live on the Custom Domains page.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Maximum deployment size | 100 MB (compressed) |
| Upload URL expiration | 15 minutes |
| Deployments per app — Playground | 2 |
| Deployments per app — Launch | 10 |
| Deployments per app — Certified | 25 |
| Deployments per app — Enterprise | Unlimited |