Branding
The Branding page lets you customize how Latch UI components look on your site. Navigate to Branding in the dashboard’s main navigation.
Customization levels
Section titled “Customization levels”Latch offers three tiers of customization. Pick one in the Customization Level card at the top of the page; the rest of the form changes to match.
Generic
Section titled “Generic”The default. Latch UI components render with the standard Latch design system (purple accent, system font, 8px border radius). No configuration needed — the form shows a single placeholder card explaining the mode and a quick Switch to Themed button when you’re ready to customize.
Themed
Section titled “Themed”Apply your publication’s brand identity to all UI components. Configured in two cards:
Visuals (colors + typography + logo, one card)
- Primary color — Buttons, links, and accent elements (color picker + hex input). The hover color is derived automatically (~10% darker via HSL); no second picker to fiddle with. To override, use Custom CSS with
--latch-primary-hover. - Font — Choose from common web fonts. Each option in the dropdown renders in its own font-face so you can preview before selecting.
- Border radius — Roundness of buttons, inputs, and cards. Use the preset chips (None / Small / Medium / Large / Full) for quick selection, or fine-tune with the slider (0–24px). The active chip highlights when the slider matches.
- Logo URL — URL to your publication’s logo (SVG or PNG). Displayed in auth modals and paywalls. Live preview shows the image inline.
Custom Text (headings, descriptions, CTA)
Override the default copy on auth and paywall components. Each field shows:
- A small hint listing the components it appears in (clickable — switches the live preview to that component).
- A character count that turns red when the value exceeds the soft limit. Limits are not enforced — they warn that the text may truncate in narrow components like
<latch-sticky-bar>.
| Field | Limit | Components |
|---|---|---|
| Sign in heading | 40 | <latch-login-form>, <latch-auth-modal> |
| Sign in description | 120 | <latch-login-form>, <latch-auth-modal> |
| Create account heading | 40 | <latch-register-form>, <latch-auth-modal> |
| Create account description | 120 | <latch-register-form>, <latch-auth-modal> |
| Paywall heading | 40 | <latch-paywall-modal>, <latch-inline-paywall>, <latch-sticky-bar>, <latch-content-lock> |
| Paywall description | 120 | <latch-paywall-modal>, <latch-inline-paywall> |
| Paywall CTA button | 24 | <latch-paywall-modal>, <latch-inline-paywall>, <latch-sticky-bar>, <latch-content-lock> |
Fully Custom
Section titled “Fully Custom”Everything in Themed, plus a CSS editor that injects custom styles directly into the Shadow DOM of every Latch UI component. Use this for:
- Changing text transforms, letter spacing, line heights
- Custom button styles beyond color
- Advanced layout adjustments
- Targeting specific internal component classes
- Overriding the auto-derived hover color (
--latch-primary-hover)
/* Example custom CSS */.latch-btn-primary { text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;}
.latch-modal { max-width: 480px;}
/* Override the auto-derived hover color */:host { --latch-primary-hover: #c0392b;}Live preview
Section titled “Live preview”The branding editor includes a live preview panel on the right side of the page. It renders the actual web component the SDK loads on your site (not a mock-up) and updates the iframe in real time as you change settings.
A dropdown above the preview lets you switch between paywall, auth, commerce, and lead-capture components. Clicking a “Shown in …” hint under any Custom Text field also switches the preview to that component.
Branding flow: dashboard → SDK render
Section titled “Branding flow: dashboard → SDK render”┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐│ Branding (main nav)│ ───▶ │ PUT /branding/admin│ ───▶ │ publication_settings││ (dashboard form) │ │ (session-auth) │ │ (DB) │└────────────────────┘ └────────────────────┘ └─────────┬──────────┘ │ ▼┌──────────────────────┐ ┌──────────────────────┐ ┌────────────────────┐│ Reader's browser │ ◀──│ GET /api/v1/branding │ ◀──│ Cached per-session ││ <latch-paywall-modal>│ │ X-API-Key: pk_… │ │ on the SDK ││ <latch-auth-modal> … │ └──────────────────────┘ └────────────────────┘└──────────────────────┘Concretely:
- Publisher edits the form in the Branding page (main nav) and clicks Save Changes. The dashboard
PUTs the config to/api/v1/branding/admin(and auto-fillsbrandColorHoverfrombrandColorif not set). - On the reader’s site,
init({ apiKey: 'pk_…' })initializes the SDK andimport '@latch/ui'triggers aGET /api/v1/brandingwith the publishable key. - The response is cached for the page session.
- Each Latch component applies the config on first render: it sets
--latch-*custom properties on its host element and pulls headings / descriptions / logo from the config when no HTML attribute overrides them.
A <latch-paywall-modal> with default branding shows the Latch purple, system font, and stock copy (“Subscribe to continue reading”). After saving a Themed config with brand color #2563eb, font Georgia, and paywall heading “Become a member”, the same <latch-paywall-modal> renders with a blue CTA, serif type, and the new heading — no code changes on the publisher’s site.
How branding is fetched on publisher sites
Section titled “How branding is fetched on publisher sites”GET /api/v1/brandingX-API-Key: pk_...The response is cached for the page session. All components apply the branding on first render (or re-render once the config arrives).
- Publisher calls
init({ apiKey: 'pk_...' })to initialize the SDK - Publisher imports
@latch/ui— this triggers the branding fetch - Components render with defaults, then re-render with branding when the fetch completes
- All subsequent component renders use the cached branding config
Priority order
Section titled “Priority order”Branding values are applied in this priority order (highest wins):
- HTML attributes on the component (e.g.
<latch-paywall-modal message="Custom">) - Dashboard branding config (fetched from the API)
- CSS custom properties set on the element or ancestor (e.g.
--latch-primary) - Default values built into the component
This means publishers can still override specific values per-component using HTML attributes, while the dashboard branding provides publication-wide defaults.
CSS custom properties (--latch-*)
Section titled “CSS custom properties (--latch-*)”Themed and Fully-Custom mode set these on the component host. Custom-CSS users can override any of them. Full reference and defaults live in the UI Components docs; the branding-related subset is:
| Property | Default | Set by |
|---|---|---|
--latch-primary | #6C5CE7 | brandColor |
--latch-primary-hover | #5A4BD1 | Auto-derived from brandColor (~10% darker) |
--latch-radius | 8px | borderRadius |
--latch-font | system-ui | fontFamily |
The full set of --latch-* variables (backgrounds, text, borders, error/success, shadows, overlay, large radius) is documented under UI Components → Theming.
API reference
Section titled “API reference”Public endpoint
Section titled “Public endpoint”GET /api/v1/brandingX-API-Key: pk_...Returns the branding configuration. Used by UI components automatically. Only accessible with a publishable key (pk_).
Admin endpoints
Section titled “Admin endpoints”GET /api/v1/branding/adminCookie: (session)PUT /api/v1/branding/adminCookie: (session)Content-Type: application/json
{ "brandingMode": "themed", "brandColor": "#e74c3c", "logoUrl": "https://example.com/logo.svg", "borderRadius": "12", "paywallHeading": "Become a member"}All fields are optional on PUT. Omitted fields are not changed. Set a field to null to clear it. The API still accepts and persists brandColorHover; the dashboard auto-fills it from brandColor when unset, so you only need to send it for non-derived hover colors (typically only Custom-CSS users).
Available fields
Section titled “Available fields”| Field | Type | Description |
|---|---|---|
brandingMode | "generic" | "themed" | "custom" | Customization level |
brandColor | string | null | Primary color hex (e.g. "#e74c3c") |
brandColorHover | string | null | Hover color hex. Auto-derived by the dashboard when unset. |
logoUrl | string | null | Logo image URL |
borderRadius | string | null | Border radius in pixels (e.g. "12") |
fontFamily | string | null | CSS font-family value |
authHeading | string | null | Sign in heading |
authDescription | string | null | Sign in description |
authRegisterHeading | string | null | Create account heading |
authRegisterDescription | string | null | Create account description |
paywallHeading | string | null | Paywall heading |
paywallDescription | string | null | Paywall description |
paywallCtaText | string | null | Paywall CTA button text |
customCss | string | null | Custom CSS (custom mode only) |