Skip to content

White-Labeling & Theming

Patrol can be deployed under a custom brand: app name, logo/favicon/manifest, OG image, and accent colors. Theming is per deployment, not per tenant — one running instance serves one brand, selected at build time via environment variables. To run multiple brands, build and deploy separate instances.

AppVariableWhere it’s read
Web (apps/web)NEXT_PUBLIC_THEMEBuild time — Next.js inlines NEXT_PUBLIC_* vars, so changing it requires a rebuild
API (apps/api)APP_NAMERuntime — used as the WebAuthn relying-party name and the Swagger doc title
Docs (apps/docs)THEMEBuild time — read by astro.config.mjs

Set NEXT_PUBLIC_THEME and THEME to the same theme ID, and APP_NAME to that theme’s app name, so all three apps present a consistent brand:

apps/web/.env
NEXT_PUBLIC_THEME=klipboard-envy
# apps/api/.env
APP_NAME=Klipboard Envy
# apps/docs/.env
THEME=klipboard-envy

Unset or unrecognized values fall back to the default patrol theme.

  • App name everywhere it appears in the web app UI — sidebar, auth/onboarding screens, page titles, breadcrumb root, and product copy throughout settings, integrations, cloud accounts, catalogue, and workflows
  • Logo mark (sidebar, auth/onboarding header, workflow provider badge)
  • Favicon, Apple touch icon, PWA manifest, and Open Graph image
  • Accent color (buttons, links, focus rings, sidebar active state, charts) via CSS custom properties
  • Brand typeface (fontFamily: "Geist" | "Inter" in ThemeConfig) — loaded via next/font/google and applied through the shared --font-sans CSS variable
  • WebAuthn relying-party name and Swagger API doc title (API)
  • The starter GitHub Actions deploy/drift-check workflow YAML — both the client-side editor defaults (apps/web/components/catalogue/workflow-editor.tsx) and the server-generated versions used by the “Install workflow” PR feature (apps/api/src/deployments/deployments.service.ts, drift-checks.service.ts, github-actions-drift.adapter.ts) — display strings only (workflow/step names, input descriptions, PR title/body, commit messages, log lines)
  • Docs site title, logo, favicon, and site URL
  • Prose content across documentation guides (integration setup steps, examples, etc.) still says “Patrol” — rewriting every guide for every theme is out of scope for the theming system itself
  • Swagger/OpenAPI operation summaries and property descriptions (@ApiOperation, @ApiProperty text) and internal source code comments — these aren’t shown to end customers, so they were left as-is to keep the change focused
  • Protocol-level identifiers are intentionally not themed, since renaming them would break already-deployed customer integrations: generated GitHub Actions/GitLab YAML keys (patrol_run_id, PATROL_CALLBACK_URL), the x-patrol-webhook-secret header, the patrol secret-manager key, the patrol:* workflow trigger namespace, the PatrolReadOnly suggested IAM role name, and the @patrol/cli npm package / patrol CLI command (a separate tool, not themed by this system)
  1. Web — add a ThemeConfig entry to apps/web/lib/theme/config.ts: app name, domain, accent colors (as CSS custom property HSL triplets — see the existing patrol entry for the format), fontFamily ("Geist" or "Inter" — add the Google Font to apps/web/app/layout.tsx if introducing a new one), and asset paths.
  2. Web assets — add mark.svg, icon.svg, and apple-icon.svg under apps/web/public/themes/<theme-id>/.
  3. Docs — add a matching entry to apps/docs/theme.config.mjs (title, description, site URL, logo/favicon paths) and the corresponding logo/favicon files under apps/docs/src/assets/ and apps/docs/public/.
  4. API — no code change needed; set APP_NAME to the new theme’s app name at deploy time.
  5. Set NEXT_PUBLIC_THEME / THEME / APP_NAME to the new theme ID for that deployment and rebuild.