This is the documentation for v10, checkout the latest version
Keycloakify
v10
  • Keycloakify
  • Release Notes & Upgrade Instructions
  • FAQ
v10
  • ๐Ÿ‘จโ€๐Ÿ’ป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
  • ๐ŸŽญ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
    • ๐Ÿ˜ž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 you users to the login/register pages
    • ๐Ÿ’ŸContributing
    • โฌ†๏ธMigration Guides
      • โฌ†๏ธv9 -> v10
      • โฌ†๏ธCRA -> Vite
      • โฌ†๏ธv8 -> v9
      • โฌ†๏ธv7 -> v8
      • โฌ†๏ธv6 -> v7
      • โฌ†๏ธv6.x -> v6.12
      • โฌ†๏ธv5 -> v6
    • ๐ŸชGoogle reCaptcha and End of third-party Cookies
    • ๐Ÿ”–Accessing the Realm Attributes
  • โญSponsors
Powered by GitBook
On this page

Was this helpful?

  1. Customization Strategies
  2. CSS Level Customization
  3. Using custom assets

CSS-in-JS

Previous.css, .sass or .lessNextComponent Level Customization

Last updated 1 month ago

Was this helpful?

TLDR: There is nothing specific to Keycloakify about importing assets. You can do it however you would in any other project.

Just if you're referencing assets that are in the public directory, use import.meta.env.BASE_URL

TLDR: You can import asset like you would in any other project, one exception being: If you reference assets that are located in your public directory from within your TSX files you must use Keycloakify's polifill of the PUBLIC_URL environnement variable, you can't use process.env.PUBLIC_URL directly:

import { PUBLIC_URL } from "keycloakify/PUBLIC_URL";
<img src={`${PUBLIC_URL}/my-image.png`} />

CSS-in-JS is preferable over plain CSS as it enables for more flexibility and is easier to maintain.

Let's see, as an example, the different ways you have to change the background image of the login page.

First let's an put it in our public directory:

If you wish to do so, you can hot swipe assets that you have placed into your public directory in your Keycloak instance files at:

yarn add @emotion/css
src/login/KcPage.tsx
import { css } from "@emotion/css";
import { Suspense, lazy } from "react";
// ...
export default function KcPage(props: { kcContext: KcContext }) {
    const { kcContext } = props;    
    // ...
    return (
        // ...
        <DefaultPage
            kcContext={kcContext}
            classes={classes}
            // ...
        />
    );
}

const classes = {
    kcBodyClass: css({
        "&&": { // Increase specificity so our rule takes precedence over the default background.
            background: `url(${import.meta.env.BASE_URL}background.png) no-repeat center center fixed`,
        }
    })
} satisfies { [key in ClassKey]?: string };
src/login/KcPages.tsx
import { css } from "@emotion/css";
import { PUBLIC_URL } from "keycloakify/PUBLIC_URL"; // You can't use process.env.PUBLIC_URL directly.
import { Suspense, lazy } from "react";
// ...
export default function KcPage(props: { kcContext: KcContext }) {
    const { kcContext } = props;    
    // ...
    return (
        // ...
        <DefaultPage
            kcContext={kcContext}
            classes={classes}
            // ...
        />
    );
}

const classes = {
    kcBodyClass: css({
        "&&": { // Increase specificity so our rule takes precedence over the default background.
            background: `url(${PUBLIC_URL}/background.png) no-repeat center center fixed`,
        }
    })
} satisfies { [key in ClassKey]?: string };

Now let's go a little further, it's even better to let the bundler generate url for your imports instead of manually referencing files from your public directory. So, let's move the background image in src/login/assets/:

And in our code import it this way:

src/login/KcPage.tsx
import { css } from "@emotion/css";
import backgroundPngUrl from "./assets/background.png";
import { Suspense, lazy } from "react";
// ...
export default function KcPage(props: { kcContext: KcContext }) {
    const { kcContext } = props;    
    // ...
    return (
        // ...
        <DefaultPage
            kcContext={kcContext}
            classes={classes}
            // ...
        />
    );
}

const classes = {
    kcBodyClass: css({
        "&&": {
            background: `url(${backgroundPngUrl}) no-repeat center center fixed`,
        }
    })
} satisfies { [key in ClassKey]?: string };

Now let's see how we can go further and apply different background on different pages of our theme:

/opt/keycloak/themes//<login|account>/resources/dist

Let's see how we can apply the image using a CSS-in-JS. In this example we'll use .

Result (see ):

๐ŸŽจ
<name of your theme>
@emotion/css
testing your theme
download a background image
Custom background successfully applied