FusionAuth developer image
FusionAuth developer logo
  • Back to site
  • Expert Advice
  • Blog
  • Developers
  • Downloads
  • Account
  • Contact sales
Navigate to...
  • Welcome
  • Getting Started
    • Getting Started
    • 5-minute Setup Guide
      • Overview
      • Docker
      • Fast Path
      • Sandbox
    • Setup Wizard & First Login
    • Register a User and Login
    • Self-service Registration
    • Start and Stop FusionAuth
    • Core Concepts
      • Overview
      • Users
      • Roles
      • Groups
      • Registrations
      • Applications
      • Tenants
      • Identity Providers
      • Authentication/Authorization
      • Integration Points
    • Example Apps
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • PHP
      • Python
      • Ruby
    • Tutorials
      • Overview
      • Java Spring
      • Python Django
  • Installation Guide
    • Overview
    • System Requirements
    • Server Layout
    • Cloud
    • Cluster
    • Docker
    • Fast Path
    • Kubernetes
      • Overview
      • Deployment Guide
      • Minikube Setup
      • Amazon EKS Setup
      • Google GKE Setup
      • Microsoft AKS Setup
    • Kickstart™
    • Homebrew
    • Marketplaces
    • Packages
    • Database
    • FusionAuth App
    • FusionAuth Search
    • Common Configuration
  • Migration Guide
    • Overview
    • General
    • Auth0
    • Keycloak
    • Amazon Cognito
    • Firebase
    • Microsoft Azure AD B2C
    • Tutorial
  • Admin Guide
    • Overview
    • Account Portal
    • Config Management
    • Editions and Features
    • Key Rotation
    • Licensing
    • Monitoring
    • Prometheus Setup
    • Proxy Setup
    • Reference
      • Overview
      • Configuration
      • CORS
      • Data Types
      • Hosted Login Pages Cookies
      • Known Limitations
      • Password Hashes
    • Releases
    • Roadmap
    • Search And FusionAuth
    • Securing
    • Switch Search Engines
    • Technical Support
    • Troubleshooting
    • Upgrading
    • WebAuthn
  • Login Methods
    • Identity Providers
      • Overview
      • Apple
      • Epic Games
      • External JWT
        • Overview
        • Example
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
        • Overview
        • Amazon Cognito
        • Azure AD
        • Discord
        • Github
        • Okta
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • SAML v2
        • Overview
        • ADFS
        • Azure AD
        • Okta
      • SAML v2 IdP Initiated
        • Overview
        • Okta
      • Xbox
    • OIDC & OAuth 2.0
      • Overview
      • Endpoints
      • Tokens
      • OAuth Modes
      • URL Validation
    • Passwordless
      • Overview
      • Magic Links
      • WebAuthn & Passkeys
    • SAML v2 IdP
      • Overview
      • Google
      • PagerDuty
      • Tableau Cloud
      • Zendesk
  • Developer Guide
    • Overview
    • API Gateways
      • Overview
      • Amazon API Gateway
      • Kong Gateway
      • ngrok Cloud Edge
    • Client Libraries & SDKs
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • Node
      • OpenAPI
      • PHP
      • Python
      • React
      • Ruby
      • Typescript
    • Events & Webhooks
      • Overview
      • Writing a Webhook
      • Securing Webhooks
      • Events
        • Overview
        • Audit Log Create
        • Event Log Create
        • JWT Public Key Update
        • JWT Refresh
        • JWT Refresh Token Revoke
        • Kickstart Success
        • Group Create
        • Group Create Complete
        • Group Delete
        • Group Delete Complete
        • Group Update
        • Group Update Complete
        • Group Member Add
        • Group Member Add Complete
        • Group Member Remove
        • Group Member Remove Complete
        • Group Member Update
        • Group Member Update Complete
        • User Action
        • User Bulk Create
        • User Create
        • User Create Complete
        • User Deactivate
        • User Delete
        • User Delete Complete
        • User Email Update
        • User Email Verified
        • User IdP Link
        • User IdP Unlink
        • User Login Failed
        • User Login Id Dup. Create
        • User Login Id Dup. Update
        • User Login New Device
        • User Login Success
        • User Login Suspicious
        • User Password Breach
        • User Password Reset Send
        • User Password Reset Start
        • User Password Reset Success
        • User Password Update
        • User Reactivate
        • User Reg. Create
        • User Reg. Create Complete
        • User Reg. Delete
        • User Reg. Delete Complete
        • User Registration Update
        • User Reg. Update Complete
        • User Reg. Verified
        • User 2FA Method Add
        • User 2FA Method Remove
        • User Update
        • User Update Complete
    • Guides
      • Overview
      • Application Specific Email Templates
      • Authentication Tokens
      • Exposing A Local Instance
      • JSON Web Tokens
      • Key Master
      • Localization and Internationalization
      • Multi-Factor Authentication
      • Multi-Tenant
      • Passwordless
      • Registration-based Email Verification
      • Searching With Elasticsearch
      • Securing Your APIs
      • Silent Mode
      • Single Sign-on
      • Two Factor (pre 1.26)
    • Integrations
      • Overview
      • CleanSpeak
      • Kafka
      • Twilio
    • Plugins
      • Overview
      • Writing a Plugin
      • Custom Password Hashing
    • User Control & Gating
      • Overview
      • Gate Unverified Users
      • Gate Unverified Registrations
      • User Account Lockout
  • Customization
    • Email & Templates
      • Overview
      • Configure Email
      • Email Templates
      • Email Variables
      • Message Templates
    • Lambdas
      • Overview
      • Apple Reconcile
      • Client Cred. JWT Populate
      • Epic Games Reconcile
      • External JWT Reconcile
      • Facebook Reconcile
      • Google Reconcile
      • HYPR Reconcile
      • JWT Populate
      • LDAP Connector Reconcile
      • LinkedIn Reconcile
      • Nintendo Reconcile
      • OpenID Connect Reconcile
      • SAML v2 Populate
      • SAML v2 Reconcile
      • SCIM Group Req. Converter
      • SCIM Group Resp. Convtr.
      • SCIM User Req. Converter
      • SCIM User Resp. Converter
      • Self-Service Registration
      • Sony PSN Reconcile
      • Steam Reconcile
      • Twitch Reconcile
      • Twitter Reconcile
      • Xbox Reconcile
    • Messengers
      • Overview
      • Generic Messenger
      • Twilio Messenger
    • Themes
      • Overview
      • Examples
      • Helpers
      • Localization
      • Template Variables
      • Kickstart Custom Theme
  • Premium Features
    • Overview
    • Advanced Registration Forms
    • Advanced Threat Detection
    • Application Specific Themes
    • Breached Password Detection
    • Connectors
      • Overview
      • Generic Connector
      • LDAP Connector
      • FusionAuth Connector
    • Entity Management
    • SCIM
      • Overview
      • Azure AD Client
      • Okta Client
      • SCIM-SDK
    • Self Service Account Mgmt
      • Overview
      • Updating User Data & Password
      • Add Two-Factor Authenticator
      • Add Two-Factor Email
      • Add Two-Factor SMS
      • Add WebAuthn Passkey
      • Customizing
      • Troubleshooting
    • WebAuthn
  • APIs
    • Overview
    • Authentication
    • Errors
    • API Explorer
    • Actioning Users
    • API Keys
    • Applications
    • Audit Logs
    • Connectors
      • Overview
      • Generic
      • LDAP
    • Consents
    • Emails
    • Entity Management
      • Overview
      • Entities
      • Entity Types
      • Grants
    • Event Logs
    • Families
    • Forms
    • Form Fields
    • Groups
    • Identity Providers
      • Overview
      • Links
      • Apple
      • External JWT
      • Epic Games
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
      • SAML v2
      • SAML v2 IdP Initiated
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • Xbox
    • Integrations
    • IP Access Control Lists
    • JWT
    • Keys
    • Lambdas
    • Login
    • Message Templates
    • Messengers
      • Overview
      • Generic
      • Twilio
    • Multi-Factor/Two Factor
    • Passwordless
    • Reactor
    • Registrations
    • Reports
    • SCIM
      • Overview
      • SCIM User
      • SCIM Group
      • SCIM EnterpriseUser
      • SCIM Service Provider Config.
    • System
    • Tenants
    • Themes
    • Users
    • User Actions
    • User Action Reasons
    • User Comments
    • WebAuthn
    • Webhooks
  • Release Notes

    Themes

    Overview

    FusionAuth themes allow you to customize the OAuth2 / OpenID Connect login pages and other user workflows such as forgot password. In FusionAuth you may create one to many themes and assign a theme per tenant or application so that you can customize the user experience for different users.

    See the corresponding Themes APIs if you’d prefer to configure FusionAuth themes via API.

    Here are the topics in this section:

    • Examples

    • Helpers

    • Localization

    • Template Variables

    • Application Specific Themes

    • Kickstart instance with Custom Theme

    Continue reading below to see how to create a theme, how to preview a theme, example code and some troubleshooting help.

    • Customization Levels

    • Create a Theme

      • Form Fields

      • Templates

    • Preview a Theme

    • Apply a Theme

    • Example Code

      • Displaying Messages

      • Customizing the Authorize Page

    • Development Tools

    • Troubleshooting

    • Upgrading

    Customization Levels

    FusionAuth theme customization is only useful if you are using the hosted login pages. Using the hosted login pages has a number of advantages. By doing so, FusionAuth handles the complexity of a number of different auth related use cases. These use cases include, but are not limited to, the following:

    • Log in

    • Log out

    • Registration

    • Forgot password

    • Email verification

    • Changing a password

    • Two factor authentication

    • Magic link passwordless authentication

    • WebAuthn/passkey passwordless authentication

    • Password expired

    • Account lockout by administrative decision or failed attempts

    • Password validation failed

    • Breach password detection

    • Federated login with IdPs such as Google and Microsoft Active Directory

    • Advanced self service registration forms

    • Linking between IdP accounts and FusionAuth accounts

    • Multi application logout (OAuth front channel logout)

    If you are not using the hosted login pages, you are responsible for creating the user interface for the login and other experiences.

    In contrast, if you are using the hosted login pages, you can customize at two different levels.

    The first is the tenant. You can do this by applying a theme at the tenant level.

    The second is the application. There are two options for applying a theme at the application level:

    • Use a tenant theme and use freemarker to switch on the client_id parameter. Review each template and ensure that you serve different content for different applications based on the Id. This is a good option if your needs are simple and you are willing to commit to the maintenance burden.

    • Use application themes. This is a paid feature. Learn more about application specific themes. This is a better choice if you have more complicated theming needs.

    Create a Theme

    FusionAuth provides the ability to create and manage themes in the UI as well as a Themes API. Any user of the FusionAuth role of admin or theme_manager may view, edit, update, and delete Themes.

    All of the FusionAuth login templates are written in FreeMarker. FreeMarker provides a very rich template language that will allow you to customize the pages and helpers to suit your needs. You can also define new macros and functions to assist you further.

    Below is an example screenshot of the Add Theme panel with each template described below.

    Create a Theme

    Form Fields

    Id Optional

    An optional UUID. When this value is omitted a unique Id will be generated automatically.

    Name Required

    A unique name to identify the theme. This name is for display purposes only and it can be modified later if desired.

    Templates

    Stylesheet (CSS) Optional

    This CSS stylesheet may be used to style the themed pages.

    This CSS will be included in the head tag in the Helpers head macro. You may also choose to include other remote stylesheets by using the <style> tag within the head macro.

    
    <style>
      ${theme.stylesheet()}
    </style>
    Messages Optional

    This section allows you to add additional localized messages to your theme. When creating an additional locale it is not required that all messages are defined for each language. If a message key is not defined for the specified locale, the value from the default bundles will be used.

    If you intend to localize your login templates, you may find our community contributed and maintained messages in our GitHub repository helpful.

    Helpers Required

    This template contains all of the main helper macros to define the head, body and footer. To begin theming FusionAuth you’ll want to start with this template as it will affect all other templates.

    See the Helpers page for additional information.

    Account edit Required Since 1.26.0

    This page contains a form that enables authenticated users to update their profile.

    /account/edit

    Account index Required Since 1.26.0

    This is the self-service account landing page. An authenticated user may use this as a starting point for operations such as updating their profile or configuring multi-factor authentication.

    /account

    Account two-factor disable Required Since 1.26.0

    This page contains a form that accepts a verification code used to disable a multi-factor authentication method.

    /account/two-factor/disable

    Account two-factor enable Required Since 1.26.0

    This page contains a form that accepts a verification code used to enable a multi-factor authentication method. Additionally, this page displays recovery codes when a user enables multi-factor authentication for the first time.

    /account/two-factor/enable

    Account two-factor index Required Since 1.26.0

    This page displays an authenticated user’s configured multi-factor authentication methods. Additionally, it provides links to enable and disable a method.

    /account/two-factor

    Account add WebAuthn passkey Required Since 1.41.0

    This page contains a form that allows a user to register a new WebAuthn passkey.

    /account/webauthn/add

    Account delete WebAuthn passkey Required Since 1.41.0

    This page contains a form that allows a user to delete a WebAuthn passkey.

    /account/webauthn/delete

    Account WebAuthn index Required Since 1.41.0

    This page displays an authenticated user’s registered WebAuthn passkeys. Additionally, it provides links to delete an existing passkey and register a new passkey.

    /account/webauthn/

    Email verification complete Required

    This page is used after a user has verified their email address by clicking the URL in the email. After FusionAuth has updated their user object to indicate that their email was verified, the browser is redirected to this page.

    /email/complete

    Email verification re-sent Required

    This page is used after a user has asked for the verification email to be resent. This can happen if the URL in the email expired and the user clicked it. In this case, the user can provide their email address again and FusionAuth will resend the email. After the user submits their email and FusionAuth re-sends a verification email to them, the browser is redirected to this page.

    /email/sent

    Email verification required Required Since 1.27.0

    This page is rendered when a user is required to verify their email address prior to being allowed to proceed with login. This occurs when Unverified behavior is set to Gated in email verification settings on the Tenant.

    /email/verification-required

    Email verification Required

    This page is rendered when a user clicks the URL from the verification email and the verificationId has expired. FusionAuth expires verificationId after a period of time (which is configurable). If the user has a URL from the verification email that has expired, this page will be rendered and the error will be displayed to the user.

    /email/verify

    Index Required Since 1.27.0

    This is the root landing page. This page is available to unauthenticated users and will be displayed whenever someone navigates to the FusionAuth host’s root page. Prior to version 1.27.0, navigating to this URL would redirect to /admin and would subsequently render the FusionAuth admin login page.

    /

    OAuth authorize Required

    This is the main login page for FusionAuth and is used for all interactive OAuth2 and OpenID Connect workflows.

    /oauth2/authorize

    OAuth authorized not registered Required Since 1.28.0

    This page is rendered when a user is not registered and the Application configuration requires registration before FusionAuth will complete the redirect.

    /oauth2/authorized-not-registered

    OAuth child registration not allowed Required

    This page contains a form where a child must provide their parent’s email address to ask their parent to create an account for them in a Consent workflow.

    /oauth2/child-registration-not-allowed

    OAuth child registration not allowed complete Required

    This page is rendered after a child provides their parent’s email address for parental consent in a Consent workflow.

    /oauth2/child-registration-not-allowed-complete

    OAuth complete registration Required

    This page contains a form that is used for users that have accounts but might be missing required fields.

    /oauth2/complete-registration

    OAuth device Required Since 1.11.0

    This page contains a form for accepting an end user’s short code for the interactive portion of the OAuth Device Authorization Grant workflow.

    /oauth2/device

    OAuth device complete Required Since 1.12.0

    This page contains a complete message indicating the device authentication has completed.

    /oauth2/device-complete

    OAuth error Required

    This page is used if the user starts or is in the middle of the OAuth workflow and any type of error occurs. This could be caused by the user messing with the URL or internally some type of information wasn’t passed between the OAuth endpoints correctly. For example, if you are federating login to an external IdP and that IdP does not properly echo the state parameter, FusionAuth’s OAuth workflow will break and this page will be displayed.

    /oauth2/error

    OAuth logout Required

    This page is used if the user initiates an OAuth logout. This page causes the user to be logged out of all associated applications or just the initiating application, as configured, via a front-channel mechanism before being redirected.

    /oauth2/logout

    OAuth passwordless Required

    This page is rendered when the user starts the passwordless login workflow. The page renders the form where the user types in their email address.

    /oauth2/passwordless

    OAuth register Required

    This page is used to register or sign up the user for the application when self-service registration is enabled.

    /oauth2/register

    OAuth start IdP link Required Since 1.28.0

    This page is used if the linking strategy of the Identity Provider is set to create a pending link. The user is presented with the option to link their account with an existing FusionAuth user account or create a new FusionAuth user.

    /oauth2/start-idp-link

    OAuth two-factor Required

    This page is used if the user has two-factor authentication enabled or two factor authentication is required and they need to type in their code again. FusionAuth will properly handle the processing on the back end. This page contains the form that the user will put their code into.

    /oauth2/two-factor

    OAuth two-factor enable Required Since 1.42.0

    This page contains a form providing a user with the Oauth2 two-factor enable form

    /oauth2/two-factor-enable

    OAuth two-factor enable complete Required Since 1.42.0

    This page contains a form providing a user with the Oauth2 two-factor enable complete form

    /oauth2/two-factor-enable-complete

    OAuth two-factor methods Required Since 1.26.0

    This page contains a form providing a user with their configured multi-factor authentication options that they may use to complete the authentication challenge.

    /oauth2/two-factor-methods

    OAuth wait Required Since 1.12.0

    This page is rendered when FusionAuth is waiting for an external provider to complete an out of band authentication request. For example, during a HYPR login this page will be displayed until the user completes authentication.

    /oauth2/wait

    OAuth WebAuthn Required Since 1.41.0

    This page contains a form where a user can enter their loginId (username or email address) to authenticate with one of their registered WebAuthn passkeys. This page uses the WebAuthn bootstrap workflow.

    /oauth2/webauthn

    OAuth WebAuthn Reauth Required Since 1.41.0

    This page contains a form that lists the WebAuthn passkeys currently available for re-authentication. A user can select one of the listed passkeys to authenticate using the corresponding passkey and user account.

    /oauth2/webauthn-reauth

    OAuth WebAuthn Reauth Enable Required Since 1.41.0

    This page contains two forms. One allows the user to select one of their existing WebAuthn passkeys to use for re-authentication. The other allows the user to register a new WebAuthn passkey for re-authentication.

    /oauth2/webauthn-reauth-enable

    OAuth Change password form Required

    This page is used if the user is required to change their password or if they have requested a password reset. This page contains the form that allows the user to provide a new password.

    /password/change

    OAuth password complete Required

    This page is used after the user has successfully updated their password, or reset it. This page should instruct the user that their password was updated and that they need to login again.

    /password/complete

    Forgot password Required

    This page is used when a user starts the forgot password workflow. This page renders the form where the user types in their email address.

    /password/forgot

    Forgot password sent Required

    This page is used when a user has submitted the forgot password form with their email. FusionAuth does not indicate back to the user if their email address was valid in order to prevent malicious activity that could reveal valid email addresses. Therefore, this page should indicate to the user that if their email was valid, they will receive an email shortly with a link to reset their password.

    /password/sent

    Verify registration complete Required

    This page is used after a user has verified their email address for a specific application (i.e. a user registration) by clicking the URL in the email. After FusionAuth has updated their registration object to indicate that their email was verified, the browser is redirected to this page.

    /registration/complete

    Verify registration re-sent Required

    This page is used after a user has asked for the application specific verification email to be resent. This can happen if the URL in the email expired and the user clicked it. In this case, the user can provide their email address again and FusionAuth will resend the email. After the user submits their email and FusionAuth re-sends a verification email to them, the browser is redirected to this page.

    /registration/sent

    Verify registration required Required Since 1.27.0

    This page is rendered when a user is required to verify their registration prior to being allowed to proceed with the registration flow. This occurs when Unverified behavior is set to Gated in registration verification settings on the Application.

    /registration/verification-required

    Verify registration Required

    This page is used when a user clicks the URL from the application specific verification email and the verificationId has expired. FusionAuth expires verificationId after a period of time (which is configurable). If the user has a URL from the verification email that has expired, this page will be rendered and the error will be displayed to the user.

    /registration/verify

    SAML logout Required Since 1.25.0

    This page is used if the user initiates a SAML logout. This page causes the user to be logged out of all associated applications via a front-channel mechanism before being redirected.

    /samlv2/logout

    Unauthorized Required Since 1.30.0

    This page is used if the user is not authorized to use the application or page. If you have advanced threat detection enabled, this page is generally made available to you.

    /unauthorized

    Preview a Theme

    If you want to see how your theme works, you can always open a browser with no active FusionAuth session and visit the hosted login pages.

    However, at times, you may need to make changes in your theme that you want to view without going through an entire registration process. You can easily do so by previewing the theme via the administrative user interface.

    Navigate to Customizations → Themes. Choose your theme, then click the preview link (the green magnifying glass):

    Preview your theme

    This will open a new tab. Click on any of the pages you’ve modified in the left hand navigation, for example OAuth register, and you’ll see the page as it would be rendered.

    Apply a Theme

    You apply a theme by configuring either a Tenant or an Application to use the theme. Each theme may apply to multiple Applications or Tenants; however, each Tenant or Application may have only one theme.

    To apply a theme to a Tenant, navigate to Tenants → Your Tenant, then select the General tab. Select the appropriate theme and save the tenant. This will apply the theme to every application in that tenant, unless there is a theme specified for an application.

    Apply a theme to a tenant.

    Note: A paid plan is required to utilize application themes.

    To apply a theme to an application, navigate to Applications → Your Application, then select the appropriate theme.

    Apply a theme to an application.

    In development, the FusionAuth theme helper project, which automatically uploads a theme to your FusionAuth instance, may be useful.

    Example Code

    Displaying Messages

    You can customize messages by locale. You can also have optional keys.

    Consider the following message bundle and theme usage example with English and German messages defined.

    English
    
    greeting=Good day
    German
    
    greeting=Guten Tag
    optional-greeting=Mitmensch
    Template
    
    <p>${theme.message('greeting')} ${theme.optionalMessage('optional-greeting')}</p>

    If I have selected German as my locale, I will be greeted with Guten Tag Mitmensch rendered on the page.

    If I have English selected I will instead find the greeting Good day optional-greeting.

    The behavior differs between theme.message and theme.optionalMessage only when the key doesn’t exist in any of the messages files, including the default one.

    When there is no suitable key found and theme.message is used, an exception is thrown and the template fails to completely render. When there is no suitable key found and theme.optionalMessage is used, the key value is returned: optional-message in the example above.

    Here’s an example of a template that will render for a user with a German locale but fail for a user with an English locale, because message fails when there is no key found:

    Template Which Will Fail For Users With an English Locale
    
    <p>${theme.message('optional-greeting')}</p>

    Here’s a Freemarker function which returns an empty string when there is no value found for an optional message:

    Freemarker Function to Return the Empty String When No Value is Found
    
    [#function getOptionalMessage key=""]
      [#if "${theme.optionalMessage(key)}" == "${key}"]
        [#return "" /]
      [/#if]
      [#return theme.optionalMessage(key) /]
    [/#function]

    If you add this to your _helpers.ftl file, you can call it like this:

    Calling getOptionalMessage
    
    [@helpers.getOptionalMessage key="optional-greeting" /]

    There’s an open issue on changing the behavior of optionalMessage.

    Customizing the Authorize Page

    Now that you have a good overview of all the templates, macros and helpers, here is an example of customizing the Authorize page.

    Let’s assume you want to change the header and footer across all of the pages including the Authorize page. This is accomplished by editing the helpers.header and helpers.footer macros. For the header, let’s assume you want to add a Sign Up and Login link. For the footer, let’s assume you want to add a link to your privacy policy. Here are the macros that include these new links:

    Custom header helper
    
    [#macro header]
      <header class="my-custom-header">
        <nav>
          <ul>
            <li class="login"><a target="_blank" href="https://my-application.com/login">Login</li>
            <li class="sign-up"><a target="_blank" href="https://my-application.com/sign-up">Sign Up</li>
          </ul>
        </nav>
      </header>
    
      [#nested/]
    [/#macro]
    Custom footer helper
    
    [#macro footer]
      <footer class="my-custom-footer">
        <nav>
          <ul>
            <li class="privacy-policy"><a target="_blank" href="https://my-application.com/privacy-policy">Privacy Policy</li>
          </ul>
        </nav>
      </footer>
    
      [#nested/]
    [/#macro]

    Once you make these changes, they will take effect on all of the pages listed above.

    Development Tools

    When building a theme, the FusionAuth theme helper project is useful.

    You can pull down all your templates, edit them locally, and have them transparently uploaded to your FusionAuth instance.

    Troubleshooting

    Theme Errors Prevent Login

    If you have edited a template and it is causing errors preventing you from logging in to FusionAuth, you can override the use of the UI templates. This will render a form allowing you to log in. To do this:

    • Open your browser and access your FusionAuth admin UI.

    • This will redirect you to the broken /oauth2/authorize page.

    • Click in your browser’s address bar and scroll to the end.

    • Add the String &bypassTheme=true to the end of the URL and hit the Enter key.

    This should render the default login page that ships with FusionAuth and allow you to log in and fix any errors you have.

    Default Theme Used Incorrectly

    Anytime a request is made to a themed page and we are unable to identify the tenant, the default tenant will be used. This includes, but is not limited to:

    • The root page / when a client_id or tenantId is not provided.

    • Any themed pages such as /password/forgot when a client_id is not provided.

    • Edge case error conditions where FusionAuth doesn’t have context to determine the application or tenant.

    If you see the default theme unexpectedly, ensure you are passing required parameters, such as the tenantId or client_id, to the page so that it can determine the applicable application or tenant. These parameters allow FusionAuth to determine the correct theme to display.

    Upgrading

    Templates

    When new functionality is introduced to the hosted login pages, new theme templates are occasionally added. They are added to the default theme by the upgrade process, but if you’ve customized your theme to fit your brand, you’ll need to modify the theme to have the new template.

    In the version release notes, any new templates and macros are documented. If there are changes, you’ll want to take a closer look at the themes post upgrade.

    As part of your upgrade testing, open the administrative user interface and navigate to Customizations > Themes.

    If any themes are missing templates, they will show as "Upgrade Required". Port the new theme files over to your custom theme, modify them as needed, and save the theme.

    Messages

    When new functionality is introduced to the hosted login pages, new theme message keys are sometimes required. They are added to the default theme messages file by the upgrade process.

    However, if you have customized your theme, the new keys are not added to that modified theme. The first time you try to modify your theme, you’ll receive an error message similar to the text below:

    
    Missing required keys. See text area below for default English translations. To continue, please copy the values from below into the Messages text area.

    FusionAuth warns you about missing required keys in order to avoid an inadvertent bad user experience. The default display for keys with no valid values in theme Messages is the key text, such as [ExternalAuthenticationException]LinkedInToken, which can be confusing for end users.

    During an upgrade, you can find these keys by testing the upgrade on a development instance or comparing releases in the fusionauth-localization repo. You can safely add these new key values to your theme prior to an upgrade. Any unused messages in a theme’s messages file are silently ignored (unless malformed).

    The extra lines won’t do any harm, and will ensure an excellent end user experience if they stumble on new functionality right after an upgrade.

    Related Posts

    • How to theme FusionAuth's advanced registration forms

    • How To Use FusionAuth's Multi-Tenant Feature To Create A Private Label Offering

    • New Feature - Login Theme

    Feedback

    How helpful was this page?

    See a problem?

    File an issue in our docs repo

    Have a question or comment to share?

    Visit the FusionAuth community forum.

    © 2023 FusionAuth
    How-to
    Subscribe for developer updates