Branding
Branding controls public logo, favicon, appearance mode, and brand values shown across public and dashboard surfaces.
On this page
Where to look
| Area | Paths |
|---|---|
| Route | src/app/(dashboard)/admin/branding/page.tsx |
| Actions and queries | src/features/branding/server/actions.ts, queries.ts |
| Repository | src/features/branding/server/repository.ts |
| Shared | src/features/branding/shared/settings.ts |
| UI | src/features/branding/ui/form.tsx |
| Uploads | src/components/uploads, src/lib/uploads |
Code-backed branding map
Admin branding surface
The admin route loads current branding values and delegates the editable form to feature UI.
src/app/(dashboard)/admin/branding/page.tsxsrc/features/branding/ui/form.tsx
Branding reads and writes
Queries, actions, and repository helpers keep public reads separate from admin mutations.
src/features/branding/server/queries.tssrc/features/branding/server/actions.tssrc/features/branding/server/repository.ts
Upload validation
Logo and favicon upload UI uses shared media helpers and server-safe file type rules.
src/components/uploads/media-uploader.tsxsrc/components/uploads/media-upload-helpers.tssrc/lib/uploads/media-types.ts
Branding update flow
- 1
Load the shared branding record
Branding settings are loaded through feature queries before the admin form renders.
src/features/branding/server/queries.ts
- 2
Validate form and media inputs
Form and upload helpers constrain appearance values and accepted media before writes.
src/features/branding/shared/settings.tssrc/lib/uploads/media-types.ts
- 3
Write through the repository
Brand updates are centralized in the branding repository so public and admin behavior stay aligned.
src/features/branding/server/actions.tssrc/features/branding/server/repository.ts
- 4
Re-check public surfaces
Marketing header, auth surfaces, dashboard shell, metadata, logo, and favicon should reflect the updated values.
src/features/branding/ui/form.tsx
Branding access guard
Source: src/features/branding/server/actions.ts
Branding writes require an authenticated profile, non-read-only access, and branding permission.
export async function updateBrandingSettings(formData: FormData) {
const supabase = await getServerSupabase();
const profile = await getActiveProfile();
if (!profile) {
return { success: false, message: "User not authenticated" };
}
if (hasReadOnlyAccess(profile)) {
return { success: false, message: "This account has read-only access and cannot make changes." };
}
const hasAccess = await canAccessAsync(profile.role, "branding");
if (!hasAccess) {
return { success: false, message: "Unauthorized: Super Admin access required" };
}Branding rules
- Validate uploaded asset type and size before storing it.
- Keep public branding reads separate from admin mutation paths.
- Check marketing nav, auth pages, dashboard header, metadata, and icons after changing brand values.