Keycloakify
HomeGitHubStorybookAlternative to keycloak-js
v11 (Legacy)
  • Documentation
  • Release Notes & Upgrade Instructions
  • FAQ
v11 (Legacy)
  • ๐Ÿ‘จโ€๐Ÿ’ปQuick start
  • ๐ŸงชTesting your Theme
    • In Storybook
    • In a Keycloak Docker Container
    • With Vite or Webpack in dev mode
  • ๐Ÿ”ฉIntegrating Keycloakify in your Codebase
    • In your React Project
      • In your Vite Project
      • In your Webpack Project
    • As a Subproject of your Monorepo
      • Turborepo
      • Nx Integrated Monorepo
      • Package Manager Workspaces
  • ๐ŸŽจCustomization Strategies
    • CSS Level Customization
      • Basic example
      • Removing the default styles
      • Applying your own classes
      • Page specific styles
      • Using Tailwind
      • Using custom assets
        • .css, .sass or .less
        • CSS-in-JS
    • Component Level Customization
      • Using custom assets
  • ๐Ÿ–‹๏ธCustom Fonts
  • ๐ŸŒŽInternationalization and Translations
    • Base principles
    • Adding Support for Extra Languages
    • Previewing you Pages In Different Languages
    • Adding New Translation Messages Or Changing The Default Ones
  • ๐ŸŽญTheme Variants
  • ๐Ÿ“Customizing the Register Page
  • ๐Ÿ‘คAccount Theme
    • Single-Page
    • Multi-Page
  • ๐Ÿ“„Terms and conditions
  • ๐Ÿ–‡๏ธStyling a Custom Page Not Included In Base Keycloak
  • ๐Ÿ”งAccessing the Server Environment Variables
  • ๐ŸŽฏTargetting Specific Keycloak Versions
  • ๐Ÿ“งEmail Customization
  • ๐Ÿš›Passing URL Parameters to your Theme
  • ๐ŸคตAdmin theme
  • ๐Ÿ“ฅImporting the JAR of Your Theme Into Keycloak
  • ๐Ÿ”›Enabling your Theme in the Keycloak Admin Console
  • ๐Ÿค“Taking ownership of the kcContext
  • ๐Ÿ“–Configuration Options
    • --project
    • keycloakVersionTargets
    • environmentVariables
    • themeName
    • startKeycloakOptions
    • themeVersion
    • postBuild
    • XDG_CACHE_HOME
    • kcContextExclusionsFtl
    • keycloakifyBuildDirPath
    • groupId
    • artifactId
    • Webpack specific options
      • projectBuildDirPath
      • staticDirPathInProjectBuildDirPath
      • publicDirPath
  • FAQ & HELP
    • ๐ŸคComunity resources
    • โฌ†๏ธMigration Guides
      • โฌ†๏ธv10->v11
      • โฌ†๏ธv9 -> v10
      • โฌ†๏ธCRA -> Vite
      • โฌ†๏ธv8 -> v9
      • โฌ†๏ธv7 -> v8
      • โฌ†๏ธv6 -> v7
      • โฌ†๏ธv6.x -> v6.12
      • โฌ†๏ธv5 -> v6
    • ๐Ÿ˜žCan't identify the page to customize?
    • ๐Ÿค”How it Works
    • ๐Ÿ˜–Some values you need are missing from in kcContext type definitions?
    • โ“Can I use it with Vue or Angular
      • Angular
    • โš ๏ธLimitations
    • ๐Ÿ›‘Errors Keycloak in Logs
    • ๐Ÿ™‹How do I add extra pages?
    • ๐Ÿค“Can I use react-hooks-form?
    • ๐Ÿš€Redirecting your users to the login/register pages
    • ๐Ÿ’ŸContributing
    • ๐ŸชGoogle reCaptcha and End of third-party Cookies
    • ๐Ÿ”–Accessing the Realm Attributes
  • โญSponsors
Powered by GitBook
On this page

Was this helpful?

Edit on GitHub
  1. Integrating Keycloakify in your Codebase
  2. In your React Project

In your Vite Project

Last updated 5 months ago

Was this helpful?

If you have a Vite/React/TypeScript project you can integrate Keycloakify directly inside it.

In this guide we're going to work with a vanilla Vite project.

Before anything make sure to commit all your pending changes so you can easily revert changes if need be.

Let's start by installing Keycloakify (and optionally Storybook) to our project:

yarn add keycloakify
yarn add --dev storybook @storybook/react @storybook/react-vite
pnpm add keycloakify
pnpm add --dev storybook @storybook/react @storybook/react-vite
bun add keycloakify
bun add --dev storybook @storybook/react @storybook/react-vite
npm install --save keycloakify
npm install --save-dev storybook @storybook/react @storybook/react-vite
cd my-react-app
git clone https://github.com/keycloakify/keycloakify-starter tmp
mv tmp/src src/keycloak-theme
mv tmp/.storybook .
rm -rf tmp
rm src/keycloak-theme/vite-env.d.ts
mv src/keycloak-theme/main.tsx src/main.tsx

Now you want to modify your entry point so that:

  • If the kcContext global is defined, render your Keycloakify theme

  • Else, reder your App as usual.

Let's say, for example, your src/main.tsx file currently looks like this:

src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import "./index.css";
import { MyProvider } from "./MyProvider";

createRoot(document.getElementById('root')!).render(
    <StrictMode>
      <MyProvider>
        <App />
      </MyProvider>
    </StrictMode>,
);

You want to rename this file to src/main.app.tsx (for example) and modify it as follow:

src/main.app.tsx
import App from "./App.tsx";
import "./index.css";
import { MyProvider } from "./MyProvider.tsx";

export default function AppEntrypoint() {
  return (
    <MyProvider>
      <App />
    </MyProvider>
  )
}

Then you want to create the following src/main.tsx file, you can copy paste the following code, it does not need to be adapted:

src/main.tsx
import { createRoot } from "react-dom/client";
import { StrictMode, lazy, Suspense } from "react";
import { KcPage, type KcContext } from "./keycloak-theme/kc.gen";
const AppEntrypoint = lazy(() => import("./main.app"));

// The following block can be uncommented to test a specific page with `yarn dev`
// Don't forget to comment back or your bundle size will increase
/*
import { getKcContextMock } from "./keycloak-theme/login/KcPageStory";

if (import.meta.env.DEV) {
    window.kcContext = getKcContextMock({
        pageId: "register.ftl",
        overrides: {}
    });
}
*/

createRoot(document.getElementById("root")!).render(
    <StrictMode>
        {window.kcContext ? (
            <KcPage kcContext={window.kcContext} />
        ) : (
            <Suspense>
                <AppEntrypoint />
            </Suspense>
        )}
    </StrictMode>
);

declare global {
    interface Window {
        kcContext?: KcContext;
    }
}

Question:

Why do my main application and Keycloak theme share the same entry point?

Answer:

To simplify the build process. If you don't want it to negatively impact the performance of your application, it's essential to understand the following points:

  • Different Contexts: The application (App) and Keycloak page (KcPage) are mounted in very different contexts. Avoid sharing providers between the two at the main.tsx file level. The true entry point of your application is the AppEntrypoint component defined in main.app.tsx, while the entry point for your Keycloak theme is the KcPage component. Be careful about what code is shared between them.

  • Responsibility of main.tsx: The main.tsx file should only determine the context (either the application or Keycloak) and mount the appropriate component (App or KcPage). It should not contain any substantial logic or dependencies.

  • Performance Considerations: Keep main.tsx as lightweight as possible to avoid increasing the initial load time of both your main application and login pages. For example, do not load any state management libraries like redux-toolkit at this level.

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({
        accountThemeImplementation: "none"
    })
  ],
})

Finally you want to add to your package.json a script for building the theme and another one to start storybook.

package.json
{
  "name": "my-react-app",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "build-keycloak-theme": "npm run build && keycloakify build",
    "storybook": "storybook dev -p 6006"
  },
  // ...

Last step is to exclude from your html <head /> things that aren't relevant in the context of Keycloak pages.

Do not blindly copy paste, this is just an example!

You have to figure out what does and does not make sense to be in the <head/> of your Keycloak UI pages.

public/index.html
<!doctype html>
<html>

<head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <meta name="keycloakify-ignore-start">
    <title>ACME Dashboard</title>
    <script>
        window.ENV = {
            API_ADDRESS: '${API_ADDRESS}',
            SENTRY_DSN: '${SENTRY_DSN}'
        };
    </script>
    <meta name="keycloakify-ignore-end">
    
    <!-- ... -->

</head>

<!-- ... -->

In the above example we tell keycloakify not to include the <title> because keycloakify will set it dynamically to something like "ACME- Login" or "ACME - Register".

We also exclude a placeholder script for injecting environment variables at container startup.

You can run npm run build-keycloak-theme, the JAR distribution of your Keycloak theme will be generated in dist_keycloak.

You're now able to use all the Keycloakify commands (npx keycloakify --help) from the root of your project.

Next we want to repatriate the relevant files from into our project:

If you have some top level await and you don't know how to deal with theses, join , I can help you out.

You also need to use Keycloakify's Vite plugin. Here we don't provide any but you probably at least want to define .

Leave accountThemeImplementation set to "none" for now. To initialize the account theme refer to .

That's it, your project is ready to go!

If you're currently using or to manage user authentication in your app you might want to checkout , the alternative from the Keycloakify team.

If you have any issues ! We're here to help!

๐Ÿ”ฉ
๐ŸŽ‰
the starter template
the discord server
build options
keycloakVersionTargets
this guide
keycloak-js
react-oidc-context
oidc-spa
reach out on Discord
๐ŸงชTesting your Theme
๐ŸŽจCustomization Strategies
Creating a new vite project with yarn create vite. You don't need to create a new project. Just use your existing codebase.
Our codebase before installing Keycloakify
State of your codebase after bringin in the Keycloakify boilerplate code. Note that the keycloak-theme (or keycloak_theme) directory can be located anywhere under your src directory.