This is the documentation for v6, checkout the latest version
Keycloakify
v5
  • Keycloakify
  • Release Notes & Upgrade Instructions
  • FAQ
v5
  • ๐ŸRequirements
  • ๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿ’ป Quick start
  • ๐ŸงชDevelopment
  • ๐Ÿ“งEmail customization
  • โœ’๏ธTerms and conditions
  • โœ…Realtime input validation
  • โš ๏ธLimitations
  • ๐ŸŒ‰Context persistence
  • ๐ŸŒAdding i18n messages keys
  • โšกPerformance optimization
  • ๐Ÿ’‚Email domain acceptlist
  • ๐Ÿ›‘Keycloak error in log
  • ๐Ÿ’ŸContributing
Powered by GitBook
On this page

Was this helpful?

Context persistence

PreviousLimitationsNextAdding i18n messages keys

Last updated 1 day ago

Was this helpful?

If, before logging in, a user has selected a specific language you don't want it to be reset to default when the user gets redirected to the login or register pages.

Same goes for the dark mode, you don't want, if the user had it enabled to show the login page with light themes.

The problem is that you are probably using localStorage to persist theses values across reload but, as the Keycloak pages are not served on the same domain that the rest of your app you won't be able to carry over states using localStorage.

The only reliable solution is to inject parameters into the URL before redirecting to Keycloak. We integrate with , by providing you a way to tell keycloak-js that you would like to inject some search parameters before redirecting.

The method also works with (use the initOptions).

You can implement your own mechanism to pass the states in the URL and restore it on the other side but we recommend using from the library that provide an elegant way to handle states such as isDarkModeEnabled.

Let's modify from the official keycloak-js documentation to enables the relevant states of our app to be injected in the URL before redirecting.

Let's say we have a boolean state isDarkModeEnabled that define if the dark theme should be enabled.

useIsDarkModeEnabled.ts

import { createUseGlobalState } from "powerhooks/useGlobalState";

export const { useIsDarkModeEnabled, $isDarkModeEnabled } = createUseGlobalState({
	"name": "isDarkModeEnabled",
  //If we don't have a previous state stored in local storage nor an URL query param
  //that explicitly set the state, we initialize using the browser preferred color scheme.
	"initialState": ()=> (
		window.matchMedia &&
		window.matchMedia("(prefers-color-scheme: dark)").matches
	),
  //Do use localStorage to persist across reloads.
	"doPersistAcrossReloads": true
});

Now let's see how we would use this state in our react app.

MyComponent.tsx

import { useIsDarkModeEnabled } from "./useIsDarkModeEnabled";

export function MyComponent(){

  const { isDarkModeEnabled, setIsDarkModeEnabled }= useIsDarkModeEnabled();

  return (
    <div>
      <p>The dark mode is currently: {isDarkModeEnabled?"enabled":"disabled"}</p>
      <button onClick={()=> setIsDarkModeEnabled(!isDarkModeEnabled)}>
        Click to toggle dark mode
      <button>
    </dvi>
  );

}

We can also update the state and track it's updates outside of react:

import { $isDarkModeEnabled } from "./useIsDarkModeEnabled";

//After 4 seconds, enable dark mode
setTimeout(
  ()=>{
      //This triggers re-renders of all the components that uses the state.
      //(the assignation has side effect)
      $isDarkModeEnabled.current = true;

  },
  4000
);

//Print something in the console anytime the state changes:  

$isDarkModeEnabled.subscribe(isDarkModeEnabled=> {
  console.log(`idDarkModeEnabled changed, new value: ${isDarkModeEnabled}`);
});

Now let's see how we would carry our isDarkModeEnabled to our login theme.

import keycloak_js from "keycloak-js";
import { injectGlobalStatesInSearchParams } from "powerhooks/useGlobalState";
import { createKeycloakAdapter } from "keycloakify";
import { addParamToUrl } from "powerhooks/tools/urlSearchParams";

//...

const keycloakInstance = keycloak_js({
    "url": "http://keycloak-server/auth",
    "realm": "myrealm",
    "clientId": "myapp",
});

keycloakInstance.init({
    "onLoad": "check-sso",
    "silentCheckSsoRedirectUri": window.location.origin + "/silent-check-sso.html",
    "adapter": createKeycloakAdapter({
        "transformUrlBeforeRedirect": url=>
            [url]
                //This will append &ui_locales=fr at on the login page url we are about to 
                //redirect to. 
                //This will tell keycloak that the login should be in french. 
                //Replace "fr" by any KcLanguageTag you have enabled on your Keycloak server.
                .map(url => addParamToUrl({ url, "name": "ui_locales", "value": "fr" }).newUrl)
                //This will make sure our isDarkModeEnabled and other global states
                //created with powerhooks/useGlobalState are restored on the other side. 
                .map(injectGlobalStatesInSearchParams)
                [0],
        keycloakInstance,
    }),
});

//...

A more production ready implementation of useIsDarkModeEnabled is available .

If you really want to go the extra miles and avoid having the white flash of the blank html before the js bundle have been evaluated that you can place in your public/index.html if you are using powerhooks/useGlobalState.

๐ŸŒ‰
keycloak-js
@react-keycloak/web
powerhooks/useGlobalState
powerhooks
the example
here
here is a snippet