Keycloakify
HomeGitHubStorybookAlternative to keycloak-js
v11
  • Documentation
  • Release Notes & Upgrade Instructions
  • FAQ
v11
  • Quick Start
  • CSS Customization
  • Testing your Theme
    • Outside of Keycloak
    • Inside of Keycloak
  • Deploying Your Theme
  • Integrating Keycloakify in your Codebase
    • Vite
    • Create-React-App / Webpack
    • yarn/npm/pnpm/bun Workspaces
    • Turborepo
    • Nx
    • Angular Workspace
  • Common Use Case Examples
    • Using a Component Library
    • Custom Fonts
    • Changing the background image
    • Adding your Logo
    • Using Tailwind
    • Dark Mode Persistence
  • Features
    • Internationalization and Translations
      • Basic principles
      • Previewing Your Pages in Different Languages
      • Adding New Translation Messages or Changing the Default Ones
      • Adding Support for Extra Languages
    • Theme Variants
    • Environment Variables
    • Styling a Custom Page Not Included in Base Keycloak
    • Integrating an Existing Theme into Your Keycloakify Project
    • Compiler Options
      • --project
      • keycloakVersionTargets
      • environmentVariables
      • themeName
      • startKeycloakOptions
      • themeVersion
      • accountThemeImplementation
      • postBuild
      • XDG_CACHE_HOME
      • kcContextExclusionsFtl
      • keycloakifyBuildDirPath
      • groupId
      • artifactId
      • Webpack specific options
        • projectBuildDirPath
        • staticDirPathInProjectBuildDirPath
        • publicDirPath
  • Page-Specific Guides
    • Registration Page
    • Terms and Conditions Page
  • Theme types
    • Differences Between Login Themes and Other Types of Themes
    • Account Theme
      • Single-Page
      • Multi-Page
    • Email Theme
    • Admin Theme
Powered by GitBook
On this page
  • Taking full control of how the KcContext is generated
  • Setting up patch-package

Was this helpful?

Edit on GitHub
  1. Features
  2. Compiler Options

kcContextExclusionsFtl

Last updated 2 months ago

Was this helpful?

. To achieve this, Keycloakify creates a global kcContext object, which holds the necessary information for generating HTML pages.

This object contains no sensitive data—only the information that the Keycloak team considers essential for rendering the various login pages. Additionally, if you have custom plugins, such as , they may introduce additional values into this object.

If you'd like to prevent some values of the FreeMarker context from being forwarded to the client you can do it with the kcContextExclusionsFtl option.

Let's say in this example that we would like to exclude:

  • kcContext.keycloakifyVersion

  • kcContext.realm.actionTokenGeneratedByUserLifespanMinutes in the register.ftl page

  • kcContext.realm.idpVerifyAccountLinkActionTokenLifespanMinutes in the register.ftl page

This is how you would do it:

vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { keycloakify } from "keycloakify/vite-plugin";

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        react(),
        keycloakify({
            // ...
            kcContextExclusionsFtl: `

                <#if (
                    xKeycloakify.pageId == "register.ftl" &&
                    [
                        "actionTokenGeneratedByUserLifespanMinutes", 
                        "idpVerifyAccountLinkActionTokenLifespanMinutes"
                    ]?seq_contains(key) &&
                    areSamePath(path, ["realm"])
                )>
                    <#continue>
                </#if>

                <#if xKeycloakify.keycloakifyVersion != "__hidden__">
                    <#assign xKeycloakify = xKeycloakify + { "keycloakifyVersion": "__hidden__" }>
                </#if>

            `
        })
    ]
});

You can also provide a path to a .ftl file instead of inlining the ftl code in your vite.config.ts file.

kcContextExclusions.ftl
<#if (
    xKeycloakify.pageId == "register.ftl" &&
    [
        "actionTokenGeneratedByUserLifespanMinutes", 
        "idpVerifyAccountLinkActionTokenLifespanMinutes"
    ]?seq_contains(key) &&
    areSamePath(path, ["realm"])
)>
    <#continue>
</#if>

<#if xKeycloakify.keycloakifyVersion != "__hidden__">
    <#assign xKeycloakify = xKeycloakify + { "keycloakifyVersion": "__hidden__" }>
</#if>
package.json
{
    "keycloakify": {
        // ...
        "kcContextExclusionsFtl": "./kcContextExclusions.ftl"
    }
}

To test/debug your exclusion when you are running npx keycloakify start-keycloak you can open the file

dist_keycloak/theme/<theme_name>/login/login.ftl

Your custom exclusion are injected around line 300. You can edit this code and reload the page immediately.

Taking full control of how the KcContext is generated

If you feel limited by this option you can take ownership of the FreeMarker template that generates the kcContext. Let's see how it can be done through an example. Some values, like for example the realm attributes (kcContext.realm.attributes) are explicitely excluded from the KcContext.

In the following video we explore how to include them back.

Note that in the video we includes all the realm attributes. We might want to expose only a specific set of values. For this we could do:

node_modules/keycloakify/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl
-    ) || (
-        key == "attributes" &&
-        areSamePath(path, ["realm"])
-    ) || (
+    ) || (
+        areSamePath(path, ["realm", "attributes"]) &&
+        !["myFirstAttribute", "mySecondAttribute"]?seq_contains(key)
+    ) || (

We could also chose to include only the realm attributes with a specific prefix, for example theme_:

node_modules/keycloakify/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl
-    ) || (
-        key == "attributes" &&
-        areSamePath(path, ["realm"])
-    ) || (
+    ) || (
+        areSamePath(path, ["realm", "attributes"]) &&
+        !key?starts_with("theme_")
+    ) || (

Setting up patch-package

As explained in the video:

yarn add --dev patch-package

Edit the FreeMarker template that generates the KcContext in:

node_modules/keycloakify/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl

You can then create a diff for your changes by running:

npx patch-package keycloakify

Then add a postinstall script to your package.json:

package.json
{
    "name": "keycloakify-starter",
    "scripts": {
        "postinstall": "patch-package",
        "dev": "vite",
    ...
}

Commit the patch/ directory that have been created by patch-package.

Add add dev dependency

patch-package
Keycloakify shifts page generation from the backend to the client
keycloak-email-whitelisting
A typical kcContext for the register.ftl page