How to customize Keycloak themes

David Wippel

David Wippel

keycloak

software development

In this insight, you will learn how Keycloak Themes are structured and how to come up with your own custom theme.

Because we believe that learning is best done when putting everything into practices, we will start off by setting up a development environment. Right after, we will go over the types of themes and the folder structure. Closing with how to add customization and build your own Keycloak theme.

Before we get started with all the details, a quick recap of what Keycloak is and why we care about it.

What is Keycloak?

Keycloak is an open-source identity and access management or IAM solution, that can be used as a third-party authorization server to manage your web or mobile applications' authentication and authorization requirements.

It lifts the heavy weight of implementing a stable and secure user authorization and authentication, from the shoulders of developers.

At TRIGO, we use it for all of our projects. It saved tons of time and money. Kept us staying sane when integrating AuthN/AuthZ into an application. We love Keycloak.

Now let's dive right into it.

Setting up a development environment

You could either download Keycloak and run it natively on your machine, or spin up some container using docker or podman.

We at TRIGO are heavily into containerization. Therefore, we will use the second option for this tutorial.

To make things even simpler for you, we have prepared a fully functional setup as Git repository.

Before proceeding with this tutorial, please take your time to check out the repository and follow the instructions found in the README file. If you got any questions, please feel free to drop me an email at hello@trigodev.com or open an issue.

Theme types

With a single theme, you can provide one or more types of customization.

An overview:

TypeDescriptionLocation the demo repository
CommonFiles (resources) shared along all theme typesthemes/keycloak-provided-themes/keycloak/common
AccountAll things related to the Account management (self-service) area.themes/keycloak-provided-themes/base/account and themes/keycloak-provided-themes/keycloak.v2/account
AdminThe admin console. Yes, the very extensive area can be customized too.themes/keycloak-provided-themes/base/admin and themes/keycloak-provided-themes/keycloak.v2/admin
EmailsEverything you need to customize Emails sent by Keycloakthemes/keycloak-provided-themes/base/email
LoginUser-facing public pages like login, password reset and so on.themes/keycloak-provided-themes/base/login and themes/keycloak-provided-themes/keycloak/login
WelcomeThe welcome page shown when spinning up Keycloak and opening its landing pagethemes/keycloak-provided-themes/keycloak/welcome

Hint: Instructions on how to configure a theme can be found in the Keycloak Documentation.

Structure of a theme folder

Every theme must consist of one or more type related subdirectories.

Structure of a theme folder

It's a 1:1 reference to the theme types mentioned above.

Structure of a theme type folder

Every theme type folder must have at least a theme.properties file. It contains basic instructions for Keycloak.

Furthermore, it consists of one or more of the following folders

FolderDescription
messagesContains one or more messages_XX.properties files. They are part of the i18n mechanism of Keycloak
resourcesEvery image, CSS or JavaScript file that is required to power the theme type is found here.

Note: The email type is a little different. It contains an HTML and text folder containing the email templates for HTML and text emails. All as FTL files.

Besides that, a theme type folder usually comes with many template files (.ftl file ending). They represent all the different pages Keycloak has.

All your base belongs to me. Theme Inheritance explained

You might have noticed that for most types, there are multiple places where you can find related files. That's because Keycloak themes are built with inheritance in mind. Everything is (or it can be) based on base (phun intended!). You could, theoretically, start from scratch, but we don't recommend that unless you have a special use case. It's just a lot of work to provide everything you need for a fully functional theme.

Theme type entry point: theme.properties

Let's have a look at the entry point of the login type.

Theme type entry point: theme.properties

This is from themes/keycloak-provided-themes/keycloak/login

The first line of theme.properties is:

parent=base

With this, we instruct Keycloak to inherit our login type from the base theme. We can then focus on the things we like to change instead of starting from zero.

FTL - Faster than light or Freemarker

Freemarker is a template language like Pug, Mustache or EJS. If you are familiar with the primary template language of your ecosystem, you should be familiar with the core concepts of freemarker too.

I still recommend going through the “Template Author Guide”. The Keycloak Login Theme makes heavy use of the FTL inheritance features. So better be prepared to dig in deep.

Data Models for your templates

Keycloak uses numerous data models within their template files. They are - let just put it that way - not very well documented.

To get at least a basic understanding, these two files from the Keycloak Source Code are a good starting point:

For Theme Type: Login

https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java

For Theme Type: Account

https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java

What other tech is included?

For the time of writing this insight, Keycloak 17 is the newest version available. There are announcements that the current angular1 based admin and account theme is replaced by a React-based solution anytime soon. Keycloak 15 already has an early version of that included. It can be found as keycloak.v2 theme here: themes/keycloak-provided-themes/keycloak.v2

The Login part of the theme uses an earlier version of the Patternfly Framework. Files:

themes/keycloak-provided-themes/keycloak/common/resources/web_modules/@patternfly

Since there is no version information available, it's hard to tell which version of Patternfly it is, but all required resources are included.

v4 of Patternfly is a remarkable framework found here.

How to customize a theme type?

For all of you who, me included, are like: Ok Patternfly is cool and what not , but I want to bring my own stuff to the table. Tailwind, Vue, Svelte, Chakra, ... just a little more patience.

Before we explore how to create a custom theme with your favorite tech stack, I think it's important to understand the structure of the default theme.

For this tutorial, I will focus on the login theme type further on. I assume that that's the type most of you want to customize anyway. Also, when you understand that part of a theme, the e.g. account part is a piece of cake for you.

The first file you should examine closer is template.ftl. It contains the basic HTML page structure and all <#nested> instructions that are used in the various templates. It defines a macro that is used in pages like login, register, login-reset-password, …

Speaking of the different templates. A quick excursion on what files are the more relevant ones:

Login theme type most relevant templates

FolderDescription
login.ftlUsername/Password login
register.ftlUser registration
login-reset-password.ftlPassword Reset
login-update-password.ftlPassword Update
login-otp.ftlOTP/2FA login
error.ftlError page

Back to customizing the login theme type

Within the FTL templates various data-models are used as mentioned above. It's beyond the scope of this tutorial to explain every detail. I strongly recommend to set aside some time to go through ALL the files and explore how the various properties are used and for what purpose.

If you got any questions, please feel free to drop me an email at hello@trigodev.com

CSS Classes confusion

Said that, there is one detail I like to explain a bit. How CSS classes are handled. It was a source of confusion for me when starting with Keycloak theme development. CSS Classes are set via properties that are defined in the theme.properties file of the login theme type.

Example:

CSS Classes confusion

I don't get the reason behind that decision. I guess the idea was to provide a way to customize the CSS classes in a central way. It was one of the first things I dropped when building the first themes for ourselves.

Included Messages for i18n

Let's assume you have added some new i18n message to one of the message_xx.properties files in the messages' folder. For example, some marketing information you want to include on the login page.

Freemarker provides a msg function to include i18n messages.

Note: It will refer to the language currently selected by the user. Keycloak uses Browser information to determine the language, but only if the language is configured.

Example:

${msg("doForgotPassword")}

Some notes on security

All things you know about web security are relevant for Keycloak themes too. Keep in mind that you are basically building a website (or web application for the account/admin theme type).

Therefore, just a few short notes on security:

Sanitizing all user-generated content

Keycloak provides a kcSanitize function to sanitize HTML content. I highly recommend using that function when including user provided HTML content in any way.

Example:

${kcSanitize(message.summary)?no_esc}

Code found here.

CSRF Protection

According to the OAUTH2 Specification, CSRF Protection is done via a state query parameter. Keycloak handles that for us via the url.loginAction property used as form action

<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">

Don't change that unless you know exactly what you are doing here.

A more detailed explanation on how the state parameter helps to prevent CSRF attacks can be found here.

Bring your own stuff

As you might have guessed, besides learning all the details about the tech stack involved and some innards about the data-model used, there is nothing special to a Keycloak theme. It's just web development. So, why not bring your well-known framework of choice to the table? The good news is that, there is no reason not to go down that road.

In fact, we do that by using Tailwind to style our themes.

I've included an example to the Git Repository. You are welcome to use that as a starting point (see themes folder).

Note: The themes are mapped into the docker-compose.yml to make them visible to Keycloak. You have to add your own theme to that by duplicating and adopt this line in the docker-compose.yml

./themes/tailwind-example/:/opt/jboss/keycloak/themes/tailwind-example/

Recap

We have learned how Keycloak themes are structured, what files are important, how inheritance works for themes and how to get started with custom themes.

I've tried to add as many lessons learned as possible. If anything isn't super clear or missing, please point that out.

Again, if you got any questions. You know how to reach out to me by now. It's hello@trigodev.com ;-)

Customizing Keycloak themes drives you crazy? We can help.

We create bespoke Keycloak themes, including login pages, self-service area and more.

Learn how

Your opinion is very important to us!

On a score of 1 to 5, what's your overall experience of our blog?
1...Very unsatisfied - 5...Very Satisfied

More insights

Why UX matters when you're building a software product

In a competitive tech market, putting your users first goes a long way. Here's a deep dive into why UX matters — and how you can prioritize it.

ux, software development, digital buiness

Read full story

5 steps you should consider before building software

Thinking about developing your own software? Here are 5 steps you should definitely consider before you start.

software development, digital buiness, discovery

Read full story

Why new software needs change management & how to plan it

Implementing a new software solution means change at every level of your business — here's where a solid change management plan comes in.

software development, digital buiness

Read full story

4 alternatives to Excel sheets for a smooth business workflow

Locked out of an Excel spreadsheet? Here are 4 alternatives to Excel to better suit your unique business needs & scale.

software development, digital buiness

Read full story

UX Case Study: Bulk Upload

A bulk upload function describes a product feature that allows the user to upload several different files at the same time and correctly process them.

software development, ux, ui

Read full story

UX vs. UI Design

Have you ever heard someone use the terms UX and UI in a discussion? These are not abbreviations for fantasy worlds or anything like that, UX and UI are among the most important components of product development.

software development, ux, ui

Read full story

See how custom business software has helped our clients succeed, no sales pitch involved. Just real-world examples. Guaranteed.

Schedule a demo