Learn Keycloak - Themes & Customization
Episode 21 of 31

Learn Keycloak - Themes & Customization

Changing Keycloak's appearance through themes: understanding the five theme types, the theme directory structure with FreeMarker templates and message bundles, plus branding and multi-language customization.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In episode 20 you tuned the realm, clients, and authentication flows. Episode 21 is about the side users see directly: themes. Keycloak's default login page is generic; by understanding the theme structure you can replace logos, colors, email templates, even add languages. Theme customization is also part of SSO service professionalism — users judge security by the appearance they trust.

The Five Theme Types

Keycloak has five theme types, each for a different surface:

Theme TypeUsed forSet at
LoginLogin, register, password reset pagesRealm Settings → Themes
AccountUser account pages (profile, sessions, password)Realm Settings → Themes
Admin ConsoleAdministrator interfaceAdmin console
EmailEmail templates (verify, reset password)Realm Settings → Themes
WelcomeWelcome page and initial admin creationServer settings

Note that the admin console and welcome themes are set at a different level from login/account/email — don't be surprised that changing the login theme doesn't change the admin console.

Theme Directory Structure

Themes live in the themes/ folder with one subfolder per type. For example themes/mytema/login/ for a custom login theme. Its core files:

ContentsDescription
theme.propertiesTheme metadata: parent, styles, import
*.ftlFreeMarker templates for pages
styles.cssPage styling
script.jsAdditional JavaScript
resources/Images and other assets
messages/Message bundles for translations

theme.properties

The most important key is parent. With parent=keycloak, your theme inherits the built-in templates so you don't need to rewrite everything:

Linuxtheme.properties in themes/mytema/login
parent=keycloak
import=common/keycloak
styles=css/styles.css

When the Keycloak version goes up, the inherited built-in templates get updated too — this is the reason to set parent rather than copying the entire theme.

FreeMarker Templates

The login pages are written as FreeMarker templates, such as login.ftl, register.ftl, and reset-password.ftl. Templates are where you change the HTML structure, not just the colors.

Customization

Branding (Logo and Colors)

Start with the easiest: put a logo in resources/, then declare it in styles.css. Without changing templates, the visual identity changes immediately across all derived pages.

Custom Login Pages

For structural changes, edit login.ftl or another template. When done, select the theme in Realm SettingsThemes and test it on the realm's login page.

Custom Error Pages

Error pages (e.g. session expired or access denied) also have their own templates, such as error.ftl. Adjust them so error messages stay clear without leaking internal details.

Custom Email Templates

The email theme contains FreeMarker templates like password-reset.ftl and email-verify.ftl. These determine the content of the password reset email discussed in episode 20 — important for branding and language.

Multi-Language Support

Translations are stored as message bundles in messages/. Create messages_id.properties for your preferred language:

LinuxMessage bundle example
loginTitle=Sign in
loginAccountTitle=Sign in to your account
doLogin=Sign in

Keycloak picks the bundle based on the user's browser locale. This way you add languages without touching a single template.

Advanced Customization

When themes alone aren't enough, Keycloak provides SPI (Service Provider Interface) for Java code extensions:

  • Custom authenticators — new authentication steps, for example OTP via SMS.
  • Custom protocol mappers — adding special claims to tokens.
  • Custom user storage providers — reading users from external sources such as LDAP or a legacy database.
  • Event listeners — capturing events for integration (covered in episode 22).

Providers are stored as JARs in the providers folder:

Installing a custom provider
cp my-provider.jar keycloak/providers/
bin/kc.sh start-dev

When the server starts, Keycloak automatically loads JARs from that folder. Test the provider in a separate environment before touching production.

Closing

In episode 21, you understood Keycloak themes: the five theme types (login, account, admin console, email, welcome), the directory structure (theme.properties, FreeMarker templates, CSS, JavaScript, resources, message bundles), branding and multi-language customization, and advanced extensions through SPI.

Key takeaways:

  • Always set parent=keycloak so themes are easy to maintain when the version goes up.
  • Message bundles bring a preferred language to life without changing templates.
  • Test themes in a staging realm before using them in production.
  • Custom SPI requires a JAR and a rebuild — manage it as part of the pipeline, not manual copy-paste.

In the next episode (episode 22), you'll make use of the activity trail: Events & Auditing — event types, event listeners, and how to record who signed in, who did what, and when.