Production Checklist
Use this list to take the editor from local to production with stable exports, secured APIs, and good performance. It is organized by topic with concrete checks and sample configs.
1) Environment and secrets
- Set your public URL:
NEXT_PUBLIC_SITE_URL
(no trailing slash). - Allow origins:
ALLOWED_ORIGINS
include your domain(s); add www/non‑www as needed. - Server keys only (no NEXT_PUBLIC_):
PEXELS_API_KEY
,TENOR_API_KEY
,MEME_API_KEY
,OPENAI_API_KEY
,TRANSCRIPTION_BEARER_TOKEN
. - Optional:
AI_REQUIRE_CLIENT_KEY
vsAI_ALLOW_SERVER_KEY
for /api/ai, route bearerAI_ROUTE_BEARER_TOKEN
.
NEXT_PUBLIC_SITE_URL=https://your.app ALLOWED_ORIGINS=https://your.app,https://www.your.app PEXELS_API_KEY=... TENOR_API_KEY=... TENOR_CLIENT_KEY=clip-js MEME_API_KEY=... OPENAI_API_KEY=... AI_REQUIRE_CLIENT_KEY=true AI_ALLOW_SERVER_KEY=false AI_ALLOW_CLIENT_KEYS=false TRANSCRIPTION_BEARER_TOKEN=... TRANSCRIPTION_WORKER_URL=https://<worker>.workers.dev
2) Security, CORS, CSP
- Origin validation: middleware checks
Origin/Referer
for all API routes. Expect 403 if misconfigured. - CSP and Permissions‑Policy are set in
middleware.ts
; confirmconnect-src
includes your providers (OpenAI, Tenor, Pexels). - COOP/COEP (optional but recommended) for multi‑threaded FFmpeg. Provided via
public/_headers
andvercel.json
. - Rate limits: global via middleware + per‑route (Tenor/Meme/Transcription). Validate in logs.
3) WASM and export engines
- Serve
/wasm/ffmpeg-core.wasm
withapplication/wasm
and long‑term cache (seepublic/_headers
). - Service Worker pre‑caches WASM in production; verify the “update available” toast appears after a redeploy.
- Desktop exports: FFmpeg WASM loads OK; Standard tab works for MP4/WebM/GIF.
- Mobile exports: MediaBunny and MediaRecorder paths work; test iOS Safari recording and share sheet.
- Transparency: Transparent tab produces WebM with alpha; optional MP4 conversion path completes.
4) Backend routes healthy
/api/health
shows AI/Transcription configured./api/ai
rejects foreign origins; succeeds with your key policy./api/transcription
succeeds (Cloudflare Worker or custom service), returns segments./api/pexels/*
and/api/tenor/search
return results; proxies stream media with correct CORS/CSP.- Meme routes require
MEME_API_KEY
and valid origin; test rate limit handling.
5) Storage, caching, and quotas
- IndexedDB projects/files store correctly;
/storage
page shows usage and SW status. - Automatic cleanup triggers >80% usage; emergency cleanup works; thumbnails persist.
- Cross‑tab migration from legacy DB completes without errors.
6) Monitoring and error reporting
- Enable Sentry DSN (optional) and verify client/server events (exports, API failures).
- Export log visible in the dialog; map common errors to actionable messages.
- API usage logging wired via
logAPIUsage
(can forward to your APM).
7) CI/CD and Node runtime
- Pin Node engine (e.g.,
"engines": {"node": ">=18 <21"}
) to avoid runtime drift. - CI passes: Build, Lint, Unit; E2E (Playwright) using
npm run dev:clean
and increased timeouts. - Type check passes (note: Next’s
params: Promise<{id}>
signature in projects/[id]/page.tsx).
8) Performance verification
- Analyze bundle:
ANALYZE_JSON=true npm run build
and inspect.next/analyze
. - Editor TTI: hover/focus prefetch warms chunks; timeline virtualization OK with large projects.
- Accessibility:
prefers-reduced-motion
respected in preview (optional enhancement).
9) Remotion Lambda (optional server rendering)
- Have a separate Remotion renderer repo; deploy with
@remotion/lambda
. - Export project bundle and upload to S3; call Lambda from a secure Next.js server route.
- Use ProRes/WebM alpha for overlays; manage costs (concurrency, memory, timeouts).
10) Deploy targets
- Vercel: headers in
vercel.json
(COOP/COEP, WASM caching). Confirm Middleware active. - Cloudflare Pages: headers in
public/_headers
for WASM and COOP/COEP. - Custom (Nginx): set
Content-Type: application/wasm
for/wasm/*
, add COOP/COEP on editor routes.
Quick post‑deploy test
- Open
/projects/new
, add a short video + text. - Export MP4 on desktop (Standard), WebM alpha (Transparent), and MP4 on mobile (MediaBunny/MediaRecorder).
- Search Tenor and Pexels; play a proxy stream.
- Run
/api/health
and make a short transcription call.