Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Sites

Generally Available

Sites hosts your web applications. It is a composer over Functions and Storage—not a separate compute primitive. Static assets live in Storage; SSR and API routes run as Functions behind an origin router.

Sites speaks the Vercel Build Output API-shaped bundle format. Framework adapters for static, Hono, and Next.js compile your project into a known target. Deploy and promote are separate: every deployment gets a preview URL; promotion swaps production traffic atomically.

Features include incremental static regeneration (ISR), on-demand revalidation, custom domains with TLS, and per-site access policies (password-protected previews, IP allowlists).

  • Framework adapters — Static, Hono, and Next.js App Router at v0; more in v0.2.
  • Preview deployments — Every build is live at {deployment_id}.preview.{site}.reactor.app.
  • Atomic promote — Single-row swap of current_deployment_id; in-flight requests finish gracefully.
  • ISR and stale-while-revalidate — Serve cached HTML; background revalidation via Jobs.
  • Custom domains — DNS or HTTP verification; ACME TLS on self-hosted (O2).
  • Route table — Static files, function dispatch, redirects, and prerender routes from manifest.
  • Unified logs — Router and function logs merged in one SSE stream.

Create a site, build a Hono app, deploy, promote, and visit the live URL.

src/index.ts (Hono):

import { Hono } from 'hono';
const app = new Hono();
app.get('/', (c) => c.json({ hello: 'Reactor Sites' }));
app.get('/api/health', (c) => c.json({ ok: true }));
export default app;
Terminal window
reactor sites create my-app --framework hono
reactor sites build ./my-hono-app --out .reactor-bundle
reactor sites deploy my-app --bundle .reactor-bundle
reactor sites promote my-app
reactor sites open my-app

Every deployment is automatically available at a preview subdomain—no promotion required.

https://{deployment_id}.preview.my-app.acme.reactor.app
Terminal window
reactor sites deploy my-app --bundle .reactor-bundle
# CLI prints preview URL from deployment ID
reactor sites deployments list my-app

Preview deployments send X-Robots-Tag: noindex and disable ISR caching so you always see fresh output.

Terminal window
reactor sites domains add my-app app.example.com
# Follow DNS TXT verification instructions
reactor sites domains verify my-app app.example.com

DNS verification record:

_reactor-verify.app.example.com TXT "reactor-site-verification={token}"

Purge cached pages after content changes.

Terminal window
reactor sites revalidate my-app --paths /blog/post-1,/blog/post-2
reactor sites revalidate my-app --tags blog
[sites]
workdir = "./.reactor/sites"
static_max_files = 50000
static_max_bytes = 536870912 # 512 MiB per deployment
isr_default_ttl_secs = 3600
preview_subdomain = "preview"
revalidation_secret = "internal-secret-for-functions"
[sites.functions]
url = "http://localhost:8004"
api_key = "internal-functions-api-key"
[sites.storage]
url = "http://localhost:8003"
api_key = "internal-storage-api-key"
[sites.jobs]
url = "http://localhost:8005"
api_key = "internal-jobs-api-key"
# Self-hosted TLS (O2)
[sites.acme]
email = "ops@example.com"

Optional analytics snippet injection in site manifest:

{
"analytics": {
"enabled": true,
"project_key": "rapk_...",
"auto_pageview": true,
"auto_errors": true
}
}
LimitDefaultNotes
Static files per deployment50,000
Total static size per deployment512 MiB
Function bundle size50 MiB eachSame as Functions
ISR default revalidate1 hourPer-route override in manifest
Invocation log sample rate1%Router traffic; use metrics for billing
Preview ISRDisabledAlways fresh on preview URLs
Edge routerv0.2Origin-based routing at v0

Route kinds in manifest:

KindBehavior
staticServe from Storage with cache headers
functionDispatch to internal SSR/API function
redirect301/302/307/308 with Location
prerenderISR cached HTML with optional fallback function

Response headers:

HeaderMeaning
X-Reactor-Site{name}@{version}
X-Reactor-CacheHIT, MISS, STALE, or BYPASS
X-Reactor-Duration-MsTotal serve latency
MethodPathDescription
POST/sites/v1/_admin/sitesCreate site
POST/sites/v1/_admin/sites/{name}/deploymentsUpload bundle
POST/sites/v1/_admin/sites/{name}/promoteSwap production traffic
POST/sites/v1/_admin/sites/{name}/revalidatePurge ISR cache
POST/sites/v1/_admin/sites/{name}/domainsAdd custom domain
GET/sites/v1/_admin/sites/{name}/logsUnified logs (SSE)

No route in the deployment’s route table matched the path and method. Check the manifest routes array—first match wins, ordered by priority.

The internal SSR function failed or timed out. Check function logs for _site-{name}-ssr. Verify the function deployment reached ready status before promote.

Deployment is still uploading assets or waiting for functions. Poll deployment status before promoting.

Terminal window
reactor sites deployments get my-app dep_01HZ...
reactor sites logs my-app --follow

Run verification again after adding the DNS TXT or HTTP challenge file:

Terminal window
reactor sites domains verify my-app app.example.com

Check X-Reactor-Cache: STALE—background revalidation may be queued. Force purge with on-demand revalidation. Ensure the ISR revalidation function deployed successfully for Next.js sites.