Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
KcContext
✓ import type { KcContext } from 'keycloakify';
✗ import { KcContext } from 'keycloakify';
This is primarily a type definition for the Keycloak context object. It should be imported as a type.
createUseKcContext
✓ import { createUseKcContext } from 'keycloakify';
✗ import { useKcContext } from 'keycloakify';
This function is used to create a custom React hook (`useKcContext`) tailored for your theme's `KcContext` definition. You call `createUseKcContext` once to get your typed hook.
useKcMessage
✓ import { useKcMessage } from 'keycloakify/lib/i18n';
✗ import { useKcMessage } from 'keycloakify';
This hook provides access to Keycloak's internationalization (i18n) messages within your React components, allowing for locale-sensitive text rendering.
This quickstart demonstrates the core structure of a Keycloakify theme: setting up an `KcApp` component to route Keycloak pages, defining a `KcContext` for type safety, and the build command to generate the `.jar` theme file. It includes a simplified `KcLogin` page as an example.
import { lazy, Suspense } from 'react';
import type { PageProps } from 'keycloakify/lib/KcProps';
import { useKcMessage } from 'keycloakify/lib/i18n';
import { createUseKcContext, get } from 'keycloakify';
import type { KcContext } from 'keycloakify';
// 1. Define your custom KcContext extension (optional)
// This example extends the context for a custom 'my-custom-page.ftl'
export type KcContextExtension = {
customData: string;
};
export type KcContextExtended = KcContext & KcContextExtension;
// 2. Create your custom useKcContext hook
export const { useKcContext } = createUseKcContext<KcContextExtension>();
// 3. Main application component that renders Keycloak pages
export default function KcApp(props: PageProps<KcContextExtended>) {
const { kcContext } = props;
const { msg } = useKcMessage();
// Dynamically set page title
if (kcContext) {
document.title = msg("doLogIn"); // Example: set based on a common message key
}
// Lazy load page components based on Keycloak's pageId
const PageComponent = kcContext ? lazy(() => {
switch (kcContext.pageId) {
case 'login.ftl': return import('./pages/KcLogin');
case 'register.ftl': return import('./pages/KcRegister');
// Add more cases for other Keycloak pages you want to customize
// For custom pages (e.g., 'my-custom-page.ftl'), ensure they are handled
case 'my-custom-page.ftl': return import('./pages/MyCustomPage');
default: return import('./pages/KcDefaultPage'); // Fallback for unhandled pages
}
}) : null;
return (
<Suspense fallback={<div>Loading Keycloak page...</div>}>
{kcContext && PageComponent ? <PageComponent {...{ kcContext }} /> : <div>No Keycloak context available.</div>}
</Suspense>
);
}
// src/keycloak-theme/pages/KcLogin.tsx (Simplified example)
// import React from 'react';
// import type { PageProps } from 'keycloakify/lib/KcProps';
// import type { KcContextExtended } from '../KcApp'; // Use your extended context
// import { useKcMessage } from 'keycloakify/lib/i18n';
// export default function KcLogin(props: PageProps<KcContextExtended>) {
// const { kcContext } = props;
// const { msg } = useKcMessage();
// return (
// <div>
// <h1>{msg('loginTitle')}</h1>
// <p>Welcome to the custom login page for {kcContext.realm.displayName}!</p>
// <form action={kcContext.url.loginAction} method='post'>
// <input type='text' id='username' name='username' placeholder={msg('username')} />
// <input type='password' id='password' name='password' placeholder={msg('password')} />
// <button type='submit'>{msg('doLogIn')}</button>
// </form>
// </div>
// );
// }
// package.json (add this script)
/*
{
"name": "my-keycloak-theme",
"version": "1.0.0",
"scripts": {
"build-keycloak-theme": "keycloakify build"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"keycloakify": "^11.0.0"
},
"devDependencies": {
"typescript": "^5.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0"
}
}
*/
keycloakify --version
Errors
Common errors & fixes
Error: Theme 'your-theme-name' not found
The generated JAR theme file was not correctly deployed to Keycloak or the theme name in Keycloak's admin console does not match the one configured in `package.json`.
fixAfter `keycloakify build`, copy the generated `.jar` file from `dist_keycloak/` to the Keycloak server's `providers` directory (e.g., `/opt/keycloak/providers/` in Docker). Ensure the `themeName` in your `package.json`'s `keycloakify` configuration matches what you select in the Keycloak admin console.
ReferenceError: kcContext is not defined
This error typically occurs during development or when trying to access `kcContext` outside the Keycloak theme's runtime environment (e.g., in your main application bundle or if the Keycloakify theme is not correctly initialized).
fixEnsure `KcApp` is correctly conditionalized to only render your Keycloak theme components when `window.kcContext` is present. During Storybook development, `kcContext` is usually mocked.
Build failed: No theme entry point found.
Keycloakify could not find the expected entry point for your theme, typically `src/keycloak-theme/KcApp.tsx` or similar, or the `keycloakify` configuration in `package.json` is incorrect.
fixVerify that your theme entry file (e.g., `src/keycloak-theme/KcApp.tsx`) exists and is correctly exporting your main theme component. Check your `package.json` for the `keycloakify` configuration and ensure `themeName` and other paths are correct.
Audit
Dependencies
No dependency data recorded yet.