跳到主要内容

White-Label & Custom Branding

White-label branding allows organizations to apply their own visual identity across the ProBeya platform. Administrators can configure brand colors, upload logos and favicons, customize the login page appearance, and optionally inject custom CSS (Enterprise plan only).

Overview​

Multi-tenant SaaS platforms often need to feel like an internal tool rather than a third-party product. ProBeya's branding system gives each organization full control over:

  • Primary & accent colors: Applied via CSS custom properties (--color-primary, --color-accent) throughout the entire UI
  • Sidebar colors: Configurable sidebar background (--sidebar-bg) and text color (--sidebar-text)
  • Header and login logos: Organization logo displayed in the sidebar, header, and login page
  • Favicon: Custom browser tab icon for a seamless branded experience
  • Login welcome text: Personalized message displayed on the login page (max 500 characters)
  • Login background image: Custom background for the authentication page
  • "Powered by ProBeya" toggle: Enterprise customers can remove the ProBeya attribution badge
  • Custom CSS injection: Enterprise customers can inject up to 10,000 characters of custom CSS

Plan Requirements​

FeatureFreeStarterProEnterprise
Custom colorsNoNoYesYes
Logo uploadsNoNoYesYes
FaviconNoNoYesYes
Login page customizationNoNoYesYes
Live previewNoNoYesYes
Remove "Powered by" badgeNoNoNoYes
Custom CSS injectionNoNoNoYes

Getting Started​

  1. Navigate to Settings > Branding from the organization settings menu.
  2. Upload your organization logo (JPEG, PNG, or SVG, max 2 MB).
  3. Set primary and accent colors using the color picker or hex input.
  4. Configure sidebar background and text colors if desired.
  5. Optionally upload a favicon (PNG, recommended 32x32).
  6. Add a welcome message for the login page.
  7. Upload a login background image for the authentication page.
  8. Use the live preview to see changes before saving.
  9. Click Save Branding to persist changes.

How It Works​

CSS Custom Properties​

Branding colors are injected as CSS custom properties at the root layout level. When an organization has custom branding configured, a <style> tag sets:

:root {
--color-primary: #115D9C; /* From brandingConfig.primaryColor */
--color-accent: #9AC443; /* From brandingConfig.accentColor */
--sidebar-bg: #1E293B; /* From brandingConfig.sidebarColor */
--sidebar-text: #F8FAFC; /* From brandingConfig.sidebarTextColor */
}

All Tailwind CSS v4 utility classes and shadcn/ui components reference these variables, so the entire UI updates automatically when branding is applied.

Logo Upload Workflow​

Branding image uploads use presigned S3 URLs for direct-to-storage uploads:

  1. The client calls branding.getUploadUrl with the asset type (logo, favicon, or loginBackground) and content type.
  2. The server generates a presigned PUT URL (15-minute expiry) and a permanent S3 key.
  3. The client uploads the file directly to S3 using the presigned URL.
  4. The client calls branding.update with the S3 key in the appropriate branding field.

This approach keeps large file transfers off the API server and leverages S3's scalable storage infrastructure.

Logo Storage​

Uploaded logos and favicons are stored in S3-compatible object storage (MinIO in development, any S3 endpoint in production). The S3 key follows the pattern:

branding/{organizationId}/{type}-{timestamp}.{extension}

Supported formats: JPEG (image/jpeg), PNG (image/png), SVG (image/svg+xml).

Tenant Isolation​

Each organization's branding is stored in the branding JSONB column on the organizations table, with customCss as a separate text column. The branding API router uses orgProcedure to ensure that:

  • Only authenticated members can read their organization's branding
  • Only admin/owner roles can update branding settings
  • Organization A's branding is never visible to Organization B
  • Branding updates are logged to the activity trail with changed field names

Live Preview​

The branding settings page includes a real-time preview panel that shows how colors will look throughout the UI. The branding.preview procedure computes CSS custom properties without persisting changes, using a three-layer merge:

  1. Preview input (user's unsaved values) — highest priority
  2. Current org branding (persisted config) — middle priority
  3. System defaults — lowest priority (ensures no variable is undefined)

Custom CSS Security​

Custom CSS (Enterprise plan only) is sanitized before storage to prevent XSS attacks. The following patterns are rejected:

  • <script tags (case-insensitive)
  • Event handler attributes (e.g., onload=, onerror=)
  • javascript: URLs

The maximum length is 10,000 characters.

API Reference​

ProcedureTypeDescription
branding.getQueryReturns current branding config for the organization
branding.updateMutationUpdates branding config with partial merge (admin/owner only)
branding.getUploadUrlMutationGenerates presigned S3 upload URL for branding assets
branding.previewQueryReturns computed CSS properties without persisting

Permissions​

ActionRequired Role
View brandingAny member
Update brandingAdmin or Owner (Pro+ plan)
Upload assetsAdmin or Owner (Pro+ plan)
Remove "Powered by" badgeEnterprise plan only
Inject custom CSSEnterprise plan only