Guides
Whitelabel guide
OpsDash can be fully white-labeled and resold as your own product — your logo, your colors, your domain, your pricing. This guide covers the complete configuration path.
What can be customized
| Element | Configurable | How |
|---|---|---|
| App name | Yes | opsdash.config.ts branding.name |
| Logo | Yes | Replace public/logo.svg and public/logo-icon.svg |
| Favicon | Yes | Replace public/favicon.ico |
| Primary color / brand palette | Yes | branding.accentColor in config (HSL value) |
| Email sender name | Yes | RESEND_FROM env var |
| Domain | Yes | Deploy to their domain |
| Pricing tiers | Yes | packages/billing/src/config/plans.ts |
| Enabled modules | Yes | modules.* in opsdash.config.ts |
| Feature limits per tier | Yes | features.* in opsdash.config.ts |
Branding configuration
// opsdash.config.ts
import { defineConfig } from '@opsdash/config';
export default defineConfig({
branding: {
name: 'AgencyOS Pro',
logo: '/logos/agencyos.png', // place file in /public/logos/
accentColor: '263 70% 50%', // HSL without hsl() — drives all primary UI
},
});The app name appears in: sidebar header, browser tab title, invitation emails, notifications.
The primary color drives all highlighted UI elements: buttons, active nav items, badges, focus rings.
Module configuration
modules: {
crm: { enabled: true },
projects: { enabled: true },
automation: { enabled: true },
billing: { enabled: true }, // disable if client doesn't need Stripe
}Disabled modules are completely hidden — they do not appear in the sidebar, search, or command palette.
Custom pricing tiers
Edit packages/billing/src/config/plans.ts to set workspace limits per tier. Update the Stripe Price IDs in .env to match your own products in the reseller's Stripe account.
// packages/billing/src/config/plans.ts
export function getPlanLimits(plan: SubscriptionPlan) {
const limits = {
free: { members: 3, storage_mb: 500, api_calls: 1000 },
pro: { members: 20, storage_mb: 25600, api_calls: 50000 },
enterprise: { members: -1, storage_mb: -1, api_calls: -1 }, // -1 = unlimited
};
return limits[plan];
}Emails
Set RESEND_FROM in .env:
RESEND_FROM="AgencyOS Pro <noreply@yourdomain.com>"This sets the sender name and address for all transactional emails (invitations, notifications, password resets).
Hiding the OpsDash attribution
If your license includes removal of attribution, locate the footer component in apps/web/src/components/layout/sidebar.tsx and remove or replace the attribution text. No other components reference the product name directly — it comes from branding.name in config.
Deployment
Deploy the whitelabeled instance exactly as a private instance — see the Private instance guide. The only difference is the branding config and, if applicable, the reseller's own Stripe account.