<p align="center">
    <img src="https://user-images.githubusercontent.com/6702424/109387840-eba11f80-7903-11eb-9050-db1dad883f78.png">  
</p>
<p align="center">
    <i>🔏 Create Keycloak themes using React 🔏</i>
    <br>
    <br>
    <a href="https://github.com/garronej/keycloakify/actions">
      <img src="https://github.com/garronej/keycloakify/workflows/ci/badge.svg?branch=main">
    </a>
    <a href="https://www.npmjs.com/package/keycloakify">
      <img src="https://img.shields.io/npm/dm/keycloakify">
    </a>
    <a href="https://github.com/garronej/keycloakify/blob/main/LICENSE">
      <img src="https://img.shields.io/npm/l/keycloakify">
    </a>
    <a href="https://github.com/thomasdarimont/awesome-keycloak">
        <img src="https://awesome.re/mentioned-badge.svg"/>
    </a>
    <a href="https://discord.gg/kYFZG7fQmn">
        <img src="https://img.shields.io/discord/1097708346976505977"/>
    </a>
    <p align="center">
        <a href="https://www.keycloakify.dev">Home</a>
        -
        <a href="https://docs.keycloakify.dev">Documentation</a>
        -
        <a href="https://storybook.keycloakify.dev">Storybook</a>
        -
        <a href="https://github.com/codegouvfr/keycloakify-starter">Starter project</a>
    </p>
</p>

<p align="center">
    <i>This build tool generates a Keycloak theme <a href="https://www.keycloakify.dev">Learn more</a></i>
    <br/>
    <br/>
    <img width="400" src="https://github.com/keycloakify/keycloakify/assets/6702424/e66d105c-c06f-47d1-8a31-a6ab09da4e80">
</p>

Keycloakify is fully compatible with Keycloak 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, [~~22~~](https://github.com/keycloakify/keycloakify/issues/389#issuecomment-1822509763), **23** [and up](https://github.com/keycloakify/keycloakify/discussions/346#discussioncomment-5889791)!

> NOTE: Keycloak 24 introduces [important changes](https://www.keycloak.org/docs/latest/upgrading/index.html#changes-to-freemarker-templates-to-render-pages-based-on-the-user-profile-and-realm).  
> We're actively working on incorporating them into Keycloakify.

## Sponsor

We are exclusively sponsored by [Cloud IAM](https://cloud-iam.com/?mtm_campaign=keycloakify-deal&mtm_source=keycloakify-github), a French company offering Keycloak as a service.  
Their dedicated support helps us continue the development and maintenance of this project.

[Cloud IAM](https://cloud-iam.com/?mtm_campaign=keycloakify-deal&mtm_source=keycloakify-github) provides the following services:

-   Simplify and secure your Keycloak Identity and Access Management. Keycloak as a Service.
-   Custom theme building for your brand using Keycloakify.

<div align="center">

![Logo Dark](https://user-images.githubusercontent.com/6702424/234135797-c84d0a90-0526-43e5-a186-70cbebdeb278.png#gh-dark-mode-only)

</div>

<div align="center">

![Logo Light](https://user-images.githubusercontent.com/6702424/234135799-68684c33-4ec5-48d4-8763-0f3922c86643.png#gh-light-mode-only)

</div>

<p align="center">
    <i>Checkout <a href="https://cloud-iam.com/?mtm_campaign=keycloakify-deal&mtm_source=keycloakify-github">Cloud-IAM</a> and use promo code <code>keycloakify5</code></i>
    <br/>
    <i>5% of your annual subscription will be donated to us, and you'll get 5% off too.</i>
</p>

Thank you, [Cloud-IAM](https://cloud-iam.com/?mtm_campaign=keycloakify-deal&mtm_source=keycloakify-github), for your support!

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tbody>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/lordvlad"><img src="https://avatars.githubusercontent.com/u/1217769?v=4?s=100" width="100px;" alt="Waldemar Reusch"/><br /><sub><b>Waldemar Reusch</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=lordvlad" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://willwill96.github.io/the-ui-dawg-static-site/en/introduction/"><img src="https://avatars.githubusercontent.com/u/10997562?v=4?s=100" width="100px;" alt="William Will"/><br /><sub><b>William Will</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=willwill96" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/Ann2827"><img src="https://avatars.githubusercontent.com/u/32645809?v=4?s=100" width="100px;" alt="Bystrova Ann"/><br /><sub><b>Bystrova Ann</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=Ann2827" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/mkreuzmayr"><img src="https://avatars.githubusercontent.com/u/20108212?v=4?s=100" width="100px;" alt="Michael Kreuzmayr"/><br /><sub><b>Michael Kreuzmayr</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=mkreuzmayr" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://coolmathgames.tech"><img src="https://avatars.githubusercontent.com/u/6877780?v=4?s=100" width="100px;" alt="Mary "/><br /><sub><b>Mary </b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=Mstrodl" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://tasyp.xyz/"><img src="https://avatars.githubusercontent.com/u/6623212?v=4?s=100" width="100px;" alt="German Öö"/><br /><sub><b>German Öö</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=Tasyp" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://revolunet.com"><img src="https://avatars.githubusercontent.com/u/124937?v=4?s=100" width="100px;" alt="Julien Bouquillon"/><br /><sub><b>Julien Bouquillon</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=revolunet" title="Code">💻</a></td>
    </tr>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/aidangilmore"><img src="https://avatars.githubusercontent.com/u/32880357?v=4?s=100" width="100px;" alt="Aidan Gilmore"/><br /><sub><b>Aidan Gilmore</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=aidangilmore" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/0x-Void"><img src="https://avatars.githubusercontent.com/u/32745739?v=4?s=100" width="100px;" alt="Void"/><br /><sub><b>Void</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=0x-Void" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/juffe"><img src="https://avatars.githubusercontent.com/u/5393231?v=4?s=100" width="100px;" alt="juffe"/><br /><sub><b>juffe</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=juffe" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/lazToum"><img src="https://avatars.githubusercontent.com/u/4764837?v=4?s=100" width="100px;" alt="Lazaros Toumanidis"/><br /><sub><b>Lazaros Toumanidis</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=lazToum" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/marcmrf"><img src="https://avatars.githubusercontent.com/u/9928519?v=4?s=100" width="100px;" alt="Marc"/><br /><sub><b>Marc</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=marcmrf" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="http://kasir-barati.github.io"><img src="https://avatars.githubusercontent.com/u/73785723?v=4?s=100" width="100px;" alt="Kasir Barati"/><br /><sub><b>Kasir Barati</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=kasir-barati" title="Documentation">📖</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/asashay"><img src="https://avatars.githubusercontent.com/u/10714670?v=4?s=100" width="100px;" alt="Alex Oliynyk"/><br /><sub><b>Alex Oliynyk</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=asashay" title="Code">💻</a></td>
    </tr>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://www.gravitysoftware.be"><img src="https://avatars.githubusercontent.com/u/1140574?v=4?s=100" width="100px;" alt="Thomas Silvestre"/><br /><sub><b>Thomas Silvestre</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=thosil" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/satanshiro"><img src="https://avatars.githubusercontent.com/u/38865738?v=4?s=100" width="100px;" alt="satanshiro"/><br /><sub><b>satanshiro</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=satanshiro" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://poelhekke.dev"><img src="https://avatars.githubusercontent.com/u/1632377?v=4?s=100" width="100px;" alt="Koen Poelhekke"/><br /><sub><b>Koen Poelhekke</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=kpoelhekke" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/zavoloklom"><img src="https://avatars.githubusercontent.com/u/4151869?v=4?s=100" width="100px;" alt="Sergey Kupletsky"/><br /><sub><b>Sergey Kupletsky</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=zavoloklom" title="Tests">⚠️</a> <a href="https://github.com/keycloakify/keycloakify/commits?author=zavoloklom" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/rome-user"><img src="https://avatars.githubusercontent.com/u/114131048?v=4?s=100" width="100px;" alt="rome-user"/><br /><sub><b>rome-user</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=rome-user" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/celinepelletier"><img src="https://avatars.githubusercontent.com/u/82821620?v=4?s=100" width="100px;" alt="Céline Pelletier"/><br /><sub><b>Céline Pelletier</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=celinepelletier" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/xgp"><img src="https://avatars.githubusercontent.com/u/244253?v=4?s=100" width="100px;" alt="Garth"/><br /><sub><b>Garth</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=xgp" title="Code">💻</a></td>
    </tr>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/BlackVoid"><img src="https://avatars.githubusercontent.com/u/673720?v=4?s=100" width="100px;" alt="Felix Gustavsson"/><br /><sub><b>Felix Gustavsson</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=BlackVoid" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://m-siemens.de/"><img src="https://avatars.githubusercontent.com/u/1873922?v=4?s=100" width="100px;" alt="Markus Siemens"/><br /><sub><b>Markus Siemens</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=msiemens" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/law108000"><img src="https://avatars.githubusercontent.com/u/8112024?v=4?s=100" width="100px;" alt="Rlok"/><br /><sub><b>Rlok</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=law108000" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/Moulyy"><img src="https://avatars.githubusercontent.com/u/115405804?v=4?s=100" width="100px;" alt="Moulyy"/><br /><sub><b>Moulyy</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=Moulyy" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/giorgoslytos"><img src="https://avatars.githubusercontent.com/u/50946162?v=4?s=100" width="100px;" alt="giorgoslytos"/><br /><sub><b>giorgoslytos</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=giorgoslytos" title="Code">💻</a></td>
    </tr>
  </tbody>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

# Changelog highlights

## 9.5

-   Post build hook: You can now apply custom transformation to your theme files. [Learn more](https://docs.keycloakify.dev/build-options#postbuild-hook).
-   You can now specify your option in the Keycloakify's Vite plugin instead in the package.json. [See example](https://docs.keycloakify.dev/build-options#themename).

## 9.4

**Vite Support! 🎉**

-   [The starter is now a Vite project](https://github.com/keycloakify/keycloakify-starter).
    The Webpack based starter is accessible [here](https://github.com/keycloakify/keycloakify-starter-cra).
-   CRA (Webpack) remains supported for the forseable future.
-   If you have a CRA Keycloakify theme that you wish to migrate to Vite checkout [this migration guide](https://docs.keycloakify.dev/migration-guides/cra-greater-than-vite).

## 9.0

Bring back support for account themes in Keycloak v23 and up! [See issue](https://github.com/keycloakify/keycloakify/issues/389).

### Breaking changes

Very few. Check them out [here](https://docs.keycloakify.dev/migration-guides/v8-greater-than-v9).

## 8.0

-   Much smaller .jar size. 70.2 MB -> 7.8 MB.  
    Keycloakify now detects which of the static resources from the default theme are actually used by your theme and only include those in the .jar.
-   Build time: The first build is slowed but the subsequent build are faster. [Update your CI so that the cache is persisted across CI build](https://github.com/keycloakify/keycloakify-starter/commit/bc378d5afb67e796f520afbc348185f3e319d9d0).

### Breaking changes

There are very few breaking changes in this major version. [Check them out](https://docs.keycloakify.dev/migration-guides/v7-greater-than-v8).

## 7.15

-   The i18n messages you defines in your theme are now also maid available to Keycloak.
    In practice this mean that you can now customize the `kcContext.message.summary` that
    display a general alert and the values returned by `kcContext.messagesPerField.get()` that
    are used to display specific error on some field of the form.
    [See video](https://youtu.be/D6tZcemReTI)

## 7.14

-   Deprecate the `extraPages` build option. Keycloakify is now able to analyze your code to detect extra pages.

## 7.13

-   Deprecate `customUserAttribute`, Keycloakify now analyze your code to predict field name usage. [See doc](https://docs.keycloakify.dev/build-options#customuserattributes).  
    It's now mandatory to [adopt the new directory structure](https://docs.keycloakify.dev/migration-guides/v6-greater-than-v7).

## 7.12

-   You can now pack multiple themes variant in a single `.jar` bundle. In vanilla Keycloak themes you have the ability to extend a base theme.
    There is now an idiomatic way of achieving the same result. [Learn more](https://docs.keycloakify.dev/build-options#keycloakify.themeVariantNames).

## 7.9

-   Separate script for copying the default theme static assets to the public directory.  
    Theses assets are only needed for testing your theme locally in Storybook or with a `mockPageId`.  
    You are now expected to have a `"prepare": "copy-keycloak-resources-to-public",` in your package.json scripts.  
    This script will create `public/keycloak-assets` when you run `yarn install` (If you are using another package manager
    like `pnpm` makes sure that `"prepare"` is actually ran.)  
    [See the updated starter](https://github.com/keycloakify/keycloakify-starter/blob/94532fcf10bf8b19e0873be8575fd28a8958a806/package.json#L11). `public/keycloak-assets` shouldn't be tracked by GIT and is automatically ignored.

## 7.7

-   Better storybook support, see [the starter project](https://github.com/keycloakify/keycloakify-starter).

## 7.0 🍾

-   Account theme support 🚀
-   It's much easier to customize pages at the CSS level, you can now see in the browser dev tool the customizable classes.
-   New interactive CLI tool `npx eject-keycloak-page`, that enables to select the page you want to customize at the component level.
-   There is [a Storybook](https://storybook.keycloakify.dev)
-   [Remember me is fixed](https://github.com/keycloakify/keycloakify/pull/272)

## 6.13

-   Build work behind corporate proxies, [see issue](https://github.com/keycloakify/keycloakify/issues/257).

## 6.12

Massive improvement in the developer experience:

-   There is now only one starter repo: https://github.com/codegouvfr/keycloakify-starter
-   A lot of comments have been added in the code of the starter to make it easier to get started.
-   The doc has been updated: https://docs.keycloakify.dev
-   A lot of improvements in the type system.

## 6.11.4

-   You no longer need to have Maven installed to build the theme. Thanks to @lordvlad, [see PR](https://github.com/keycloakify/keycloakify/pull/239).
-   Feature new build options: [`bundler`](https://docs.keycloakify.dev/build-options#keycloakify.bundler), [`groupId`](https://docs.keycloakify.dev/build-options#keycloakify.groupid), [`artifactId`](https://docs.keycloakify.dev/build-options#keycloakify.artifactid), [`version`](https://docs.keycloakify.dev/build-options#version).  
    Theses options can be user to customize the output name of the .jar. You can use environnement variables to overrides the values read in the package.json. Thanks to @lordvlad.

## 6.10.0

-   Widows compat (thanks to @lordvlad, [see PR](https://github.com/keycloakify/keycloakify/pull/226)). WSL is no longer required 🎉

## 6.8.4

-   `@emotion/react` is no longer a peer dependency of Keycloakify.

## 6.8.0

-   It is now possible to pass a custom `<Template />` component as a prop to `<KcApp />` and every
    individual page (`<Login />`, `<RegisterUserProfile />`, ...) it enables to customize only the header and footer for
    example without having to switch to a full-component level customization. [See issue](https://github.com/keycloakify/keycloakify/issues/191).

## 6.7.0

-   Add support for `webauthn-authenticate.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/keycloakify/keycloakify/pull/185).

## 6.6.0

-   Add support for `login-password.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/keycloakify/keycloakify/pull/184).

## 6.5.0

-   Add support for `login-username.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/keycloakify/keycloakify/pull/183).

## 6.4.0

-   You can now optionally pass a `doFetchDefaultThemeResources: boolean` prop to every page component and the default `<KcApp />`
    This enables you to prevent the default CSS and JS that comes with the builtin Keycloak theme to be downloaded.  
    You'll get [a black slate](https://user-images.githubusercontent.com/6702424/192619083-4baa5df4-4a21-4ec7-8e28-d200d1208299.png).

## 6.0.0

-   Bundle size drastically reduced, locals and component dynamically loaded.
-   First print much quicker, use of React.lazy() everywhere.
-   Real i18n API.
-   Actual documentation for build options.

Checkout [the migration guide](https://docs.keycloakify.dev/v5-to-v6)

## 5.8.0

-   [React.lazy()](https://reactjs.org/docs/code-splitting.html#reactlazy) support 🎉. [#141](https://github.com/keycloakify/keycloakify/issues/141)

## 5.7.0

-   Feat `logout-confirm.ftl`. [PR](https://github.com/keycloakify/keycloakify/pull/120)

## 5.6.4

Fix `login-verify-email.ftl` page. [Before](https://user-images.githubusercontent.com/6702424/177436014-0bad22c4-5bfb-45bb-8fc9-dad65143cd0c.png) - [After](https://user-images.githubusercontent.com/6702424/177435797-ec5d7db3-84cf-49cb-8efc-3427a81f744e.png)

## 5.6.0

Add support for `login-config-totp.ftl` page [#127](https://github.com/keycloakify/keycloakify/pull/127).

## 5.3.0

Rename `keycloak_theme_email` to `keycloak_email`.  
If you already had a `keycloak_theme_email` you should rename it `keycloak_email`.

## 5.0.0

[Migration guide](https://github.com/garronej/keycloakify-demo-app/blob/a5b6a50f24bc25e082931f5ad9ebf47492acd12a/src/index.tsx#L46-L63)  
New i18n system.  
Import of terms and services have changed. [See example](https://github.com/garronej/keycloakify-demo-app/blob/a5b6a50f24bc25e082931f5ad9ebf47492acd12a/src/index.tsx#L46-L63).

## 4.10.0

Add `login-idp-link-email.ftl` page [See PR](https://github.com/keycloakify/keycloakify/pull/92).

## 4.8.0

[Email template customization.](#email-template-customization)

## 4.7.4

**M1 Mac** support (for testing locally with a dockerized Keycloak).

## 4.7.2

> WARNING: This is broken.  
> Testing with local Keycloak container working with M1 Mac. Thanks to [@eduardosanzb](https://github.com/keycloakify/keycloakify/issues/43#issuecomment-975699658).  
> Be aware: When running M1s you are testing with Keycloak v15 else the local container spun will be a Keycloak v16.1.0.

## 4.7.0

Register with user profile enabled: Out of the box `options` validator support.  
[Example](https://user-images.githubusercontent.com/6702424/158911163-81e6bbe8-feb0-4dc8-abff-de199d7a678e.mov)

## 4.6.0

`tss-react` and `powerhooks` are no longer peer dependencies of `keycloakify`.
After updating Keycloakify you can remove `tss-react` and `powerhooks` from your dependencies if you don't use them explicitly.

## 4.5.3

There is a new recommended way to setup highly customized theme. See [here](https://github.com/garronej/keycloakify-demo-app/blob/look_and_feel/src/KcApp/KcApp.tsx).  
Unlike with [the previous recommended method](https://github.com/garronej/keycloakify-demo-app/blob/a51660578bea15fb3e506b8a2b78e1056c6d68bb/src/KcApp/KcApp.tsx),
with this new method your theme wont break on minor Keycloakify update.

## 4.3.0

Feature [`login-update-password.ftl`](https://user-images.githubusercontent.com/6702424/147517600-6191cf72-93dd-437b-a35c-47180142063e.png).  
Every time a page is added it's a breaking change for non CSS-only theme.  
Change [this](https://github.com/garronej/keycloakify-demo-app/blob/df664c13c77ce3c53ac7df0622d94d04e76d3f9f/src/KcApp/KcApp.tsx#L17) and [this](https://github.com/garronej/keycloakify-demo-app/blob/df664c13c77ce3c53ac7df0622d94d04e76d3f9f/src/KcApp/KcApp.tsx#L37) to update.

## 4

-   Out of the box [frontend form validation](#user-profile-and-frontend-form-validation) 🥳
-   Improvements (and breaking changes in `import { useKcMessage } from "keycloakify"`.

## 3

No breaking changes except that `@emotion/react`, [`tss-react`](https://www.npmjs.com/package/tss-react) and [`powerhooks`](https://www.npmjs.com/package/powerhooks) are now `peerDependencies` instead of being just dependencies.  
It's important to avoid problem when using `keycloakify` alongside [`mui`](https://mui.com) and
[when passing params from the app to the login page](https://github.com/keycloakify/keycloakify#implement-context-persistence-optional).

## 2.5

-   Feature [Use advanced message](https://github.com/keycloakify/keycloakify/blob/59f106bf9e210b63b190826da2bf5f75fc8b7644/src/lib/i18n/useKcMessage.tsx#L53-L66)
    and [`messagesPerFields`](https://github.com/keycloakify/keycloakify/blob/59f106bf9e210b63b190826da2bf5f75fc8b7644/src/lib/getKcContext/KcContextBase.ts#L70-L75) (implementation [here](https://github.com/keycloakify/keycloakify/blob/59f106bf9e210b63b190826da2bf5f75fc8b7644/src/bin/build-keycloak-theme/generateFtl/common.ftl#L130-L189))
-   Test container now uses Keycloak version `15.0.2`.

## 2

-   It's now possible to implement custom `.ftl` pages.
-   Support for Keycloak plugins that introduce non standard ftl values.
    (Like for example [this plugin](https://github.com/micedre/keycloak-mail-whitelisting) that define `authorizedMailDomains` in `register.ftl`).
