DocsDeployment

Vercel deployment, env vars, and PWA config

Deployment

Surflink is designed to deploy on Vercel as a standard Next.js application.

Vercel Deployment

Quick Deploy

  1. Connect your GitHub repository to Vercel
  2. Vercel auto-detects the Next.js framework
  3. Configure environment variables in the Vercel dashboard
  4. Deploy

Build Settings

The default Next.js build configuration works out of the box:

SettingValue
FrameworkNext.js
Build Commandnext build
Output Directory.next
Install Commandnpm install
Node.js Version18.x

Environment Variables

Set all required environment variables in Vercel's project settings:

Required

VariableDescription
NEXT_PUBLIC_MODAL_API_URLModal (SurfVision) API base URL
NEXT_PUBLIC_SUPABASE_URLSupabase project URL
NEXT_PUBLIC_SUPABASE_ANON_KEYSupabase public/anon key
RESEND_API_KEYResend email API key
RESEND_FROM_EMAILEmail sender address
STREAM_SIGNING_SECRETHMAC secret for video stream tokens

Optional (Frame.io)

VariableDescription
FRAMEIO_CLIENT_IDFrame.io OAuth client ID
FRAMEIO_CLIENT_SECRETFrame.io OAuth client secret
FRAMEIO_REDIRECT_URIMust point to your production domain: https://yourdomain.com/api/auth/frameio/callback

Optional (Push Notifications)

VariableDescription
APNS_KEY_IDAPNs key ID
APNS_TEAM_IDApple Developer Team ID
APNS_PRIVATE_KEYAPNs .p8 private key
APNS_BUNDLE_IDiOS app bundle ID
APNS_ENVIRONMENTSet to production for live deployments

PWA Configuration

Web App Manifest

The PWA manifest is at public/manifest.json and configures:

  • App name: Surflink
  • Theme color: #97FB57 (accent mint)
  • Display: Standalone
  • Categories: Sports, Education, Productivity
  • Icons: Multiple sizes for various devices

Service Worker

The service worker at public/sw.js is registered on page load via a script in the root layout. It provides:

  • Basic offline caching strategy
  • Asset caching for faster subsequent loads

The service worker is registered in src/app/layout.js:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js').catch(() => {})
  })
}

CORS & Headers

Video Streaming

The /api/video/stream endpoint requires special handling:

  • Excluded from auth middleware to avoid 431 (Header Too Large) errors from range requests
  • Protected by HMAC-signed tokens instead (/api/video/sign issues time-limited tokens)
  • Supports byte-range requests for video scrubbing
  • Allowlists Modal, Supabase, and Frame.io as video sources

SharedArrayBuffer

FFmpeg WASM (used for client-side video compression) requires SharedArrayBuffer, which needs these headers:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

Configure these in next.config.mjs or Vercel's headers configuration if client-side compression is needed in production.

Database Deployment

The Supabase database is managed separately:

  1. Create a Supabase project at supabase.com
  2. Run supabase/schema.sql in the SQL Editor
  3. Copy the project URL and anon key to your environment variables
  4. RLS policies ensure data isolation without additional server-side checks

Monitoring

  • Vercel Analytics -- Built-in performance monitoring
  • Supabase Dashboard -- Database metrics, auth logs, storage usage
  • Modal Dashboard -- AI processing job status and logs