Advanced Branding with Themes
Customize SecureAuth identity experiences per workspace by creating and binding custom themes. Themes allow advanced control over HTML structure, messages, and components.
Use advanced branding to build tenant-specific or organization-specific login flows, messages, and layouts using templates and reusable components.
What Can Be Customized
- Login, Consent, MFA, and Error Pages
- Messages (email/SMS)
- Reusable Components (e.g., headers, footers)
- Full HTML layout, structure, and behavior via Golang templates
Create a Theme
Steps to Create
- Go to Tenant Settings > Appearance, and open the Themes tab.
- Click + CREATE THEME.
- Enter a unique theme name.
- (Optional) Add a logo/icon URL to identify this theme in the UI.
- Click Create.
Result: Your new theme appears in the list.
Want to Duplicate?
Use the three-dot menu next to any theme > Duplicate Theme to reuse or iterate from an existing one.
Edit Templates
- In the Themes list, click the theme you want to customize to open the theme editor.
- Navigate the three template categories:
| Template Type | Description |
|---|---|
| Pages | UI pages (Login, Consent, MFA, Error) |
| Messages | Outgoing email or SMS messages |
| Components | Common HTML blocks reused across templates |
Use the live preview panel to test page and message templates as you edit.
Tip: You can insert OTPs or variables using [[OTP]], [[User.Email]], etc.
Scripts in page templates
Add nonce="{{ .Config.Nonce }}" to every <script> tag in a page template, both inline and external. A nonce-based Content Security Policy only runs scripts that carry the per-request nonce:
<script nonce="{{ .Config.Nonce }}">
document.getElementById("sign-in-form").addEventListener("submit", function (event) {
// your logic
});
</script>
A nonce-based policy also blocks inline event handler attributes such as onclick or onsubmit, and javascript: links. Attach handlers with addEventListener from a script that carries the nonce.
Where the nonce lives depends on the data the template receives:
| Template | Nonce expression |
|---|---|
Page templates (pages/...) and partials called with the whole page, as in {{ template "my_partial" . }} | {{ .Config.Nonce }} |
shared/header.tmpl, which receives .Config | {{ .Nonce }} |
Partials called with a dict | Pass the nonce in: {{ template "my_partial" dict "Nonce" .Config.Nonce }}, then use {{ .Nonce }} inside |
If you override shared/header.tmpl, both ways of calling the language selector get the nonce: {{ template "language_selector" .I18n }} and the built-in header's call:
{{ template "language_selector" dict "I18n" .I18n "Nonce" .Nonce "CurrentLocale" .I18n.CurrentLocale "SupportedLocales" .I18n.SupportedLocales "SelectorEnabled" .I18n.SelectorEnabled }}
If you add your own scripts to the header, use {{ .Nonce }} or {{ .I18n.Nonce }}.
Bind a Theme to a Workspace
Themes are scoped per workspace.
- From the Themes list, click the three dots next to your theme.
- Select Bind to Workspace.
- Choose the workspace and click Save.
Each workspace can have only one active theme at a time.
To see which workspaces use a theme, click Show workspaces in the theme's row.
CI/CD Integration
For production use, you can:
- Store and manage themes in source control
- Use the CI/CD repo integration to promote changes across environments
Preview Themes
- View live updates inside the preview editor.
- Switch between page types (Login, Consent, MFA, etc.)
- Visual validation before publishing.
Summary of Advanced Branding Options
| Area | What You Control |
|---|---|
| Pages | HTML layout and styles |
| Messages | Email/SMS content and branding |
| Components | Shared UI parts across templates |
| Workspace Binding | Assign different themes per org |
| CI/CD | Automate and version-control themes |
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Save disabled | Template error | Open browser console for syntax issues |
| Preview broken | Malformed HTML or tokens | Validate placeholders and layout |
| Changes not applied | Theme not bound | Ensure workspace has correct theme |
| Script does not run | Missing CSP nonce | Add nonce="{{ .Config.Nonce }}" to the <script> tag |
Related Topics
- Branding overview
- Simple branding setup
- Customize emails and messages
- Vanity domains