Skip to main content
Streamly is one Next.js application with host-aware routing. The same deploy serves the operator console, viewer storefront, marketing/legal pages, and /api/v1 tenant APIs.

High-Level Layout

Surfaces

Operator (/admin)

System-operator console for the purchase/license holder. Sidebar items come from lib/operator/nav.ts — Overview, Users, Subscriptions, Plans, Catalog, Addons, Brand & Experience, Themes, Posts, Plugins, Settings. See Admin Dashboard Overview.

Viewer storefront (app/(viewer)/)

Public OTT routes: home, browse, movies/shows, title detail, watch, live, pricing, account, profiles. Look is driven by the active theme package (templateEntry) and Brand & Experience config — not by forking routes per theme. See Storefront Overview.
  • Platform host pretty URLs (/about, /terms, …) rewrite to /site/*.
  • Tenant-branded landing content also exists under app/(landing)/.
  • Legal markdown is bundled at build time for Cloudflare Workers (no runtime fs).
See Legal & Marketing Pages.

APIs

Tenant Resolution

Host → tenant via lib/streamly/tenant-context.ts: Reserved platform hosts include streamly.watch, www, admin, app, api.

Themes & Branding Architecture

  1. Theme packages live under themes/<id>/ (theme.json, config.ts, skin.ts, template).
  2. One route tree; skins via templateEntryStorefrontThemeProvider / getStorefrontSkin.
  3. HTML sets data-storefront-theme so CSS chrome stays isolated per theme.
  4. Per-theme look memory: theme_presets[themeId] inside landing config.
  5. Preview: /?__theme_preview=<themeId> (operator-only, in-memory).
Deep dive: Themes & Skins, Themes Package System.

Data Plane

All durable state is in Supabase. Apply every file in supabase/migrations/ in numeric order — there is no single schema.sql. See Database Schema.

Deploy Targets