Using custom assets

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

Let's say you want to put te logo of your company on every pages of the theme.

First you'd eject the Template:

npx keycloakify eject-page # Select login -> Template.tsx

This will create a src/login/Template.tsx file in your project.

Import from the public directory

Let's use this placeholder for the demo: logo.png.

We put the file in public/img/logo.png

Now let's edit the template to import the file:

src/login/Template.tsx
export default function Template(props: TemplateProps<KcContext, I18n>) {

    return (
        <div className={kcClsx("kcLoginClass")}>
            <div id="kc-header" className={kcClsx("kcHeaderClass")}>
                <div id="kc-header-wrapper" className={kcClsx("kcHeaderWrapperClass")}>
                    {/*{msg("loginTitleHtml", realm.displayNameHtml)}*/}
                    <img src={`${import.meta.env.BASE_URL}img/logo.png`} width={500}/>
                </div>
            </div>
            {/* ... */}

You can see the result by running npx keycloakify start-keycloak

If you ever need to SSH into the Keycloak server and hot swipe the image you can find it at

/opt/keycloak/themes/<name of your theme>/login/resources/dist/img/logo.png

Letting the bundle handle your import

Importing your asset from the public directory has the drawback that you won't get a compilation error if you made a mistake, like for example if you rename a file and forget to update the imports. A nice solution for this is to let Vite or Webpack handle the import.

Let's move our logo.png to /src/login/assets/logo.png

Now let's update the imports:

src/login/Template.tsx
import logoPngUrl from "./assets/logo.png";

export default function Template(props: TemplateProps<KcContext, I18n>) {

    return (
        <div className={kcClsx("kcLoginClass")}>
            <div id="kc-header" className={kcClsx("kcHeaderClass")}>
                <div id="kc-header-wrapper" className={kcClsx("kcHeaderWrapperClass")}>
                    {/*{msg("loginTitleHtml", realm.displayNameHtml)}*/}
                    <img src={logoPngUrl} width={500}/>
                </div>
            </div>
            {/* ... */}

This will yield the same result except that now if you delete, move or rename the logo.png file you'll get a compilation error letting you know that you must also update your Template.tsx file.

Last updated