If your app offers a dark/light mode, you might be wondering how to “transfer” that mode to your login theme. This ensures that if users are browsing your app in dark mode, then click “Login,” they’ll be redirected to a Keycloakify login UI that’s rendered in dark mode.
This is somewhat of a niche use case, but it illustrates how you can pass state from your application to your Keycloak UIs.
In Your Web Application
Typically, when your user clicks your “Login” button in the header, your application will redirect them to a URL that looks something like this:
The following snippet is a React component typically placed in the header of your application for displaying Login and Register buttons.
import { useOidc } from"oidc";import { useTheme } from"@mui/material/styles";import Button from"@mui/material/Button";import { assert } from"tsafe/assert";exportfunctionAuthButtons() {const { isUserLoggedIn,login } =useOidc();assert(!isUserLoggedIn,"If this component is rendered, the user should not be logged in" );consttheme=useTheme();constextraQueryParams= { dark:theme.palette.mode ==="dark"?"true":"false",// ui_locales is a special query param that Keycloak recognizes.// You can set it to make sure the login pages are// displayed in the correct language. ui_locales:"en" };return ( <> <ButtononClick={() =>login({ doesCurrentHrefRequiresAuth:false, extraQueryParams }) } > Login </Button> <Buttonvariant="contained"onClick={() =>login({ doesCurrentHrefRequiresAuth:false,transformUrlBeforeRedirect: url => {consturlObj=newURL(url);urlObj.pathname =urlObj.pathname.replace(/\/auth$/,"/registrations" );returnurlObj.href; }, extraQueryParams }) } > Register </Button> </> );}
In Your Login Theme
Within your Keycloak theme, you can now create a utility to read your custom &dark=true|false parameter.
src/shared/isDark.ts
constSESSION_STORAGE_KEY="isDark";functiongetIsDark():boolean|undefined { from_url: {consturl=newURL(window.location.href);constvalue=url.searchParams.get("dark");if (value ===null) {// There was no &dark= query param in the URL,// so we check session storage next.break from_url; }// Remove &dark= from the URL (just to keep it clean)url.searchParams.delete("dark");window.history.replaceState({},"",url.toString());constisDark= value ==="true";// Persist the value in session storage so that// if the user navigates, for example, from login.ftl to// register.ftl, we don’t lose the state.sessionStorage.setItem(SESSION_STORAGE_KEY,`${isDark}`);return isDark; } from_session_storage: {constvalue=sessionStorage.getItem(SESSION_STORAGE_KEY);if (value ===null) {break from_session_storage; }return value ==="true"; }returnundefined;}
How you use this utility depends heavily on your framework and UI library. As an example, here’s what it might look like with React/MUI: