How to add a custom field to the Keycloak registration page

The default Keycloak registration page comes with a set of fields that are supposed to be useful in most installations. You can see them in the following screenshot:

Although the decision of providing separated first and last name fields is controversial, this set of fields can certainly be a good default for several countries/cultures. But how do you extend this form to collect some other user details like, for example, a phone number or an address?

Keycloak does not provide a user interface to manage this form in its admin panel, the solution I am proposing in this post involves a custom theme and some changes to the default registration page template, register.ftl.

Implementation

Suppose you want to add the phone field to the registration form, the code to add would be the following:

<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('phone',properties.kcFormGroupErrorClass!)}">
  <div class="${properties.kcLabelWrapperClass!}">
    <label for="user.attributes.phone" class="${properties.kcLabelClass!}">${msg("phone")}</label>
  </div>
  <div class="${properties.kcInputWrapperClass!}">
    <input
      type="text"
      id="user.attributes.phone"
      class="${properties.kcInputClass!}"
      name="user.attributes.phone"
      value="${(register.formData['user.attributes.phone']!'')}"
    />
  </div>
</div>

As you can see it's just a matter of using user.attributes.phone as an identifier to your new input field and setting it's value to a Freemarker template variable (check also the label for field).

Add this to your template and activate your custom theme from the Keycloak administration interface. The field should now appear in your registration form.

If you try to register a new user the phone number will be stored, you can retrieve this value in the Keycloak administration panel: select a user and under the Attributes tab you will find a list of key-value items which contains the phone field you just created and it's value.

Comments