Skip to content

Branding

The Branding page lets you customize how Latch UI components look on your site. Navigate to Branding in the dashboard’s main navigation.

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.

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.

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>.
FieldLimitComponents
Sign in heading40<latch-login-form>, <latch-auth-modal>
Sign in description120<latch-login-form>, <latch-auth-modal>
Create account heading40<latch-register-form>, <latch-auth-modal>
Create account description120<latch-register-form>, <latch-auth-modal>
Paywall heading40<latch-paywall-modal>, <latch-inline-paywall>, <latch-sticky-bar>, <latch-content-lock>
Paywall description120<latch-paywall-modal>, <latch-inline-paywall>
Paywall CTA button24<latch-paywall-modal>, <latch-inline-paywall>, <latch-sticky-bar>, <latch-content-lock>

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;
}

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 (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:

  1. 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-fills brandColorHover from brandColor if not set).
  2. On the reader’s site, init({ apiKey: 'pk_…' }) initializes the SDK and import '@latch/ui' triggers a GET /api/v1/branding with the publishable key.
  3. The response is cached for the page session.
  4. 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/branding
X-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).

  1. Publisher calls init({ apiKey: 'pk_...' }) to initialize the SDK
  2. Publisher imports @latch/ui — this triggers the branding fetch
  3. Components render with defaults, then re-render with branding when the fetch completes
  4. All subsequent component renders use the cached branding config

Branding values are applied in this priority order (highest wins):

  1. HTML attributes on the component (e.g. <latch-paywall-modal message="Custom">)
  2. Dashboard branding config (fetched from the API)
  3. CSS custom properties set on the element or ancestor (e.g. --latch-primary)
  4. 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.

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:

PropertyDefaultSet by
--latch-primary#6C5CE7brandColor
--latch-primary-hover#5A4BD1Auto-derived from brandColor (~10% darker)
--latch-radius8pxborderRadius
--latch-fontsystem-uifontFamily

The full set of --latch-* variables (backgrounds, text, borders, error/success, shadows, overlay, large radius) is documented under UI Components → Theming.

GET /api/v1/branding
X-API-Key: pk_...

Returns the branding configuration. Used by UI components automatically. Only accessible with a publishable key (pk_).

GET /api/v1/branding/admin
Cookie: (session)
PUT /api/v1/branding/admin
Cookie: (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).

FieldTypeDescription
brandingMode"generic" | "themed" | "custom"Customization level
brandColorstring | nullPrimary color hex (e.g. "#e74c3c")
brandColorHoverstring | nullHover color hex. Auto-derived by the dashboard when unset.
logoUrlstring | nullLogo image URL
borderRadiusstring | nullBorder radius in pixels (e.g. "12")
fontFamilystring | nullCSS font-family value
authHeadingstring | nullSign in heading
authDescriptionstring | nullSign in description
authRegisterHeadingstring | nullCreate account heading
authRegisterDescriptionstring | nullCreate account description
paywallHeadingstring | nullPaywall heading
paywallDescriptionstring | nullPaywall description
paywallCtaTextstring | nullPaywall CTA button text
customCssstring | nullCustom CSS (custom mode only)