Keycloakify - Keycloak UI customization

Sun, February 16, 2025 - 3 min read

Contents

Setup Keycloakify project

# clone project
git clone https://github.com/keycloakify/keycloakify-starter
git remote set-url origin git@gitlab.com:{gitlab-group}/keycloak-theme-tps.git # change git remote to your gitlab group

# install dependencies
cd keycloakify-starter/
bun install

# preview UI with storybook
bun --bun run storybook

# start keycloak docker server
sudo apt-get install maven
bunx keycloakify start-keycloak

# add or eject page
bunx keycloakify add-story # Select login.ftl (for example)
bunx keycloakify eject-page
bunx keycloakify initialize-account-theme

Developing

Add UI dependencies

bun install -d tailwindcss postcss autoprefixer prettier-plugin-tailwindcss
  • Create main.css file in src/login/, then import in src/login/KcPage.tsx

  • Run storybook to preview UI. Find class in coresponding component and customize it to main.css file. See tutorial in https://docs.keycloakify.dev/css-customization

Customize page

  • If you want to customize login page, you must eject it first

    bunx keycloakify eject-page
    // src/login/KcPage.tsx
    
    const LoginUpdatePassword = lazy(() => import('./pages/LoginUpdatePassword')); 
    
    ...
    
            switch (kcContext.pageId) {
              case 'login.ftl':
                return <Login {...{ kcContext, i18n, classes }} Template={Template} doUseDefaultCss={false} />;
              case 'login-update-password.ftl': 
                return ( 
                  <LoginUpdatePassword {...{ kcContext, i18n, classes }} Template={Template} doUseDefaultCss={false} />
                ); 
    
// tailwind.config.js

export default {
  theme: {
    extend: {
      backgroundImage: { 
        'img-logo': "url('./assets/images/logo.png')",
        'img-logo-slogan': "url('./assets/images/logo-slogan.png')",
      },
    },
  },
};
.kcHeaderWrapperClass {
  @apply size bg-img-logo bg-contain bg-no-repeat;
  @apply text-transparent !important;
}

Add icons

If you want to optimize font file size, import svg from google font icon using icomoon, then export to font file (woff and tff)

  • Add some code

    // tailwind.config.js
    export default {
      theme: {
        extend: {
          fontFamily: {
            'material-icons': ['Material Icons Sharp']
          },
        }
      }
    }
    /* main.css */
    @font-face {
      font-family: 'Material Icons Sharp';
      /* src: url('./assets/fonts/MaterialSymbolsSharp[FILL,GRAD,opsz,wght].woff2') format('woff2'); */
      src:
        url('./assets/fonts/font.woff') format('woff'),
        url('./assets/fonts/font.tff') format('truetype');
    }
    
    // Add icons user and visibility to login form
    .usernameIcon,
    .kcFormPasswordVisibilityIconHide,
    .kcFormPasswordVisibilityIconShow {
      @apply absolute right-4 top-[2.6rem] font-material-icons text-xl not-italic;
      font-variation-settings:
        'FILL' 0,
        'wght' 300,
        'GRAD' 0,
        'opsz' 48;
    }
    
    .usernameIcon::after {
      content: '\e7fd'; /* person */
      @apply text-2xl;
    }
    
    .kcFormPasswordVisibilityIconHide::after {
      content: '\e8f5'; /* visibility_off */
    }
    .kcFormPasswordVisibilityIconShow::after {
      content: '\e8f4'; /* visibility */
    }
    ...
    

Build & Deploy

  • Change theme name

    // src/kc.gen.tsx
    export type ThemeName = 'keycloakify-starter'; 
    export type ThemeName = 'tps'; 
    
    export const themeNames: ThemeName[] = ['keycloakify-starter']; 
    export const themeNames: ThemeName[] = ['tps']; 
  • Change Keycloak version targets

    // src/kc.gen.tsx
      plugins: [
        react(),
        keycloakify({
          themeName: 'tps',
          accountThemeImplementation: 'Multi-Page',
          keycloakVersionTargets: { '21-and-below': false, '23': false, '24': false, '25': false, '26-and-above': true } 
        })
  • Build

    # build
    bun build-keycloak-theme # or
    bun run build-keycloak-theme # create .jar file in dist.
    
    # copy `keycloak-theme-for-kc-26-and-above.jar` file to keycloak server
    scp \\wsl.localhost\...\keycloakify-starter\dist_keycloak\keycloak-theme-for-kc-26-and-above.jar {remote-server}:{path}/keycloak/themes
  • Deploy in keycloak container: mount theme to /opt/keycloak/providers/

    ...
    volumes:
    - ./themes:/opt/keycloak/providers/
    ...

References: