Let's see firs how you can overwrite the default translation messages to best fit your usecases.
See, for example, by default the login page shows "Sign in to your account":
Let's say we want to change that with a message more specific to you usecase.
First setup is to identify the message key. You can usually found it just by inspecting the HTML of your page:
Here we can see that the "Sign in to your account" translation message corespond to the message key loginAccountTitle.
Let's change the English and French translations:
Here is the result that you should get:
The translations that you provide to the i18nBuilder
must be statically valuable. You can't import from external files. All the translations must be declared inline.
This is because Keycloakify will analyze your code at build time to make Keycloak aware of your modifications of the base messages so that server side generated feedback messages can use your translations.
If you have opted for a configuration at the component level it can come handy to define you own custom message keys:
You'll then be able to use the message key "myCustomMessage" in your components:
If you are implementing theme variants you can provides translations on a per-theme variant basis. See how.
Now this is perfect for defining generale purpose text. But some other translations messages are more specific to a specific Keycloak configuration and are best configured via the Keycloak Account Console. I'm thinking in particular as translations related to custom user attribues (favourite pet for example) or terms and conditions.
Some relevant messages, namely termsText
and all the messages used in the User Profile Attributes like for example the Display name, the helper text or the select option labels can be defined at the realm level and it will work as you would expect:
Note that if you try to use:
It will work at runtime, you'll get Favourite Pet
but typescript will complain because "profile.attributes.favourite_pet"
or string
isn't a known i18n message key, it makes sense as it's only defined on the server.
This is why you'll see in some place in the code the usage of advancedMsg(attribute.displayName)
, advancedMsg()
is basically equivalent to msg()
except that TypeScript won't complain if the key isn't part of the statically defined set.
More details.
See also: