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
| Feature | Free | Starter | Pro | Enterprise |
|---|---|---|---|---|
| Custom colors | No | No | Yes | Yes |
| Logo uploads | No | No | Yes | Yes |
| Favicon | No | No | Yes | Yes |
| Login page customization | No | No | Yes | Yes |
| Live preview | No | No | Yes | Yes |
| Remove "Powered by" badge | No | No | No | Yes |
| Custom CSS injection | No | No | No | Yes |
Getting Started
- Navigate to Settings > Branding from the organization settings menu.
- Upload your organization logo (JPEG, PNG, or SVG, max 2 MB).
- Set primary and accent colors using the color picker or hex input.
- Configure sidebar background and text colors if desired.
- Optionally upload a favicon (PNG, recommended 32x32).
- Add a welcome message for the login page.
- Upload a login background image for the authentication page.
- Use the live preview to see changes before saving.
- 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:
- The client calls
branding.getUploadUrlwith the asset type (logo,favicon, orloginBackground) and content type. - The server generates a presigned PUT URL (15-minute expiry) and a permanent S3 key.
- The client uploads the file directly to S3 using the presigned URL.
- The client calls
branding.updatewith 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:
- Preview input (user's unsaved values) — highest priority
- Current org branding (persisted config) — middle priority
- 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:
<scripttags (case-insensitive)- Event handler attributes (e.g.,
onload=,onerror=) javascript:URLs
The maximum length is 10,000 characters.
API Reference
| Procedure | Type | Description |
|---|---|---|
branding.get | Query | Returns current branding config for the organization |
branding.update | Mutation | Updates branding config with partial merge (admin/owner only) |
branding.getUploadUrl | Mutation | Generates presigned S3 upload URL for branding assets |
branding.preview | Query | Returns computed CSS properties without persisting |
Permissions
| Action | Required Role |
|---|---|
| View branding | Any member |
| Update branding | Admin or Owner (Pro+ plan) |
| Upload assets | Admin or Owner (Pro+ plan) |
| Remove "Powered by" badge | Enterprise plan only |
| Inject custom CSS | Enterprise plan only |
Related Features
- Custom Domains — Use your own domain with branded login
- Embeddable Widgets — Branded read-only embeds for external stakeholders