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.
Selecting a theme
Section titled “Selecting a theme”| App | Variable | Where it’s read |
|---|---|---|
Web (apps/web) | NEXT_PUBLIC_THEME | Build time — Next.js inlines NEXT_PUBLIC_* vars, so changing it requires a rebuild |
API (apps/api) | APP_NAME | Runtime — used as the WebAuthn relying-party name and the Swagger doc title |
Docs (apps/docs) | THEME | Build 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:
NEXT_PUBLIC_THEME=klipboard-envy
# apps/api/.envAPP_NAME=Klipboard Envy
# apps/docs/.envTHEME=klipboard-envyUnset or unrecognized values fall back to the default patrol theme.
What’s covered
Section titled “What’s covered”- 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"inThemeConfig) — loaded vianext/font/googleand applied through the shared--font-sansCSS 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
What’s not covered
Section titled “What’s not covered”- 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,@ApiPropertytext) 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), thex-patrol-webhook-secretheader, thepatrolsecret-manager key, thepatrol:*workflow trigger namespace, thePatrolReadOnlysuggested IAM role name, and the@patrol/clinpm package /patrolCLI command (a separate tool, not themed by this system)
Adding a new theme
Section titled “Adding a new theme”- Web — add a
ThemeConfigentry toapps/web/lib/theme/config.ts: app name, domain, accent colors (as CSS custom property HSL triplets — see the existingpatrolentry for the format),fontFamily("Geist"or"Inter"— add the Google Font toapps/web/app/layout.tsxif introducing a new one), and asset paths. - Web assets — add
mark.svg,icon.svg, andapple-icon.svgunderapps/web/public/themes/<theme-id>/. - Docs — add a matching entry to
apps/docs/theme.config.mjs(title, description, site URL, logo/favicon paths) and the corresponding logo/favicon files underapps/docs/src/assets/andapps/docs/public/. - API — no code change needed; set
APP_NAMEto the new theme’s app name at deploy time. - Set
NEXT_PUBLIC_THEME/THEME/APP_NAMEto the new theme ID for that deployment and rebuild.