Overriding UI elements

Authenticators providing UI implement the same pattern regarding styling. It is possible to style a single authenticator and/or use a global pattern making all authenticators use the same styles.

Making the authenticator read the updated files

In order to make the authenticator read the custom file instead of the default file the configuration parameter overlay_dir must be used on each authenticator.

Add parameter "overlay_dir":<path_to_custom_directory>.

In the custom directory create a folder, "assets", and place the updated file. Restart system.

It is possible to use the same override file for multiple authenticators.

Favicon

in the assets folder of your overlay_dir, place the favicon.ico.

All of the authenticator frontend/UI applications use the same type of configuration files.

The preferred way of configuring the files is using the overlay_dir.

css_overrides.css

Configure the css_overrides.css file in the assets/ folder of your overlay_dir

The file is empty by default. To override the css variables used in the applications see all the default values below. Note, if you wish to only override for example the button background color you do not need to include the rest of the variables.

Default values/available variables

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  src: url('fonts/font-inter/inter-regular.woff2') format('woff2'),
    url('fonts/font-inter/inter-regular.woff') format('woff');
}
@font-face {
  font-family: 'Inter var';
  font-weight: 100 900;
  font-display: swap;
  font-style: normal;
  font-named-instance: 'Regular';
  src: url('fonts/font-inter/inter-roman.var.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter var';
  font-weight: 100 900;
  font-display: swap;
  font-style: italic;
  font-named-instance: 'Italic';
  src: url('fonts/font-inter/inter-italic.var.woff2') format('woff2');
}

:root {
  --color-primary: #024550;
  --color-accent: #00cc7e;
  --color-background: #181830;
  --color-surface: #ffffff;
  --color-backface: #f5f5f5;
  --color-on-primary: #ffffff;
  --color-on-surface: var(--color-primary);
  
  --color-button-background: #181830;
  --color-button-background-hover: #c7f3aa;
  --color-button-background-disabled: #d4d4d4;
  --color-button-text: #ffffff;
  --color-button-text-hover: #181830;
  --color-button-text-disabled: #181830;
  --color-link: #045e6c;
  --color-link-hover: #058194;
  --color-link-text-disabled: #bcbcbc;
  --button-radius: 0rem;
  
  --background-image: url('bg_login.svg') no-repeat center center/cover fixed;
  --background-fallback-color: var(--color-background);
  --color-header-background: var(--color-primary);
  --color-header-text: var(--color-on-primary);
  --color-progress-filled: #024550;
  --color-progress-background: #e2e8e9;
  --color-loader-indicator-bottom: #00ca7b;
  --color-loader-indicator-middle: #02444e;
  --color-loader-indicator-top: rgba(200, 200, 200, 0.7);
}

html {
  color: var(--color-on-surface);
  background-color: var(--background-fallback-color);
  background: var(--background-image), var(--background-fallback-color);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
    'Segoe UI Symbol';
}
@supports (font-variation-settings: normal) {
  html {
    font-family: 'Inter var', -apple-system, BlinkMacSystemFont, 'Segoe UI',
      Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji',
      'Segoe UI Emoji', 'Segoe UI Symbol';
  }
}
@media (min-width: 521px) and (max-height: 915px) {
  :root {
    font-size: 95%;
  }
}
@media (min-width: 521px) and (max-height: 880px) {
  :root {
    font-size: 90%;
  }
}
@media (min-width: 521px) and (max-height: 830px) {
  :root {
    font-size: 85%;
  }
}
@media (min-width: 521px) and (max-height: 760px) {
  :root {
    font-size: 82%;
  }
}
.loader {
  position: relative;
  width: 77px;
  height: 48px;
  background: #00ca7b;
  background: var(--color-loader-indicator-bottom);
  transform: rotateX(65deg) rotate(45deg);
  color: #02444e;
  color: var(--color-loader-indicator-middle);
  animation: layers1 1s linear infinite alternate;
}
.loader:after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(200, 200, 200, 0.7);
  background: var(--color-loader-indicator-top);
  animation: layerTr 1s linear infinite alternate;
}
@keyframes layers1 {
  0% {
    box-shadow: 0px 0px 0 0px;
  }
  90%,
  100% {
    box-shadow: 20px 20px 0 -4px;
  }
}
@keyframes layerTr {
  0% {
    transform: translate(0, 0) scale(1);
  }
  100% {
    transform: translate(-25px, -25px) scale(1);
  }
}

Examples

Example: To update the button backgrounds define in your css_overrides.css:

:root {
  --color-button-background: 242deg 34% 14%;
  --color-button-background-hover: 242 34% 20%;
  --color-button-text: 0deg 0% 100%;
  --color-button-text-hover: 0deg 0% 90%;
}

Example: To change background image

Make sure image is available in the assets folder (using the overlay method preferably) and define in your css_overrides.css

:root {
  --background-image: url('new_background_image.png') no-repeat center center fixed;
}

ui_config_overrides.json

Configure the ui_config_overrides.json. Use overlay to provide the custom file and place the file in <overlay_dir>/assets/ui_config_overrides.json. The data in ui_config_overrides.json will be merged with the default values (below)

Name
Description
Default value

vendor.logo.src

The src of the bottom vendor logo. If undefined or empty string "" no logo will be shown

"assets/fortified_logo_green.svg"

vendor.logo.size

The size of the bottom vendor logo.

"40px"

vendor.link.url

URL for vendor logo

"https://fortifiedid.se/"

vendor.link.text

If undefined or empty string "" no link text will be shown

""

supportedLanguages

List of supported languages. If a language is specified here it is assumed to be available under the folder assets/locales/<code>.json See more in section below

title

Browser tab title

"Fortified ID"

localesMergePath

Path for merging locale files. If omitted or empty string "" is used no locale merging will be done. Important: must end with /

""

fallbackLanguage

Default/fallback language if user has not saved a language in cookies

"sv"

Customizing translations

There are two possible ways to customize the locale files, either by

  1. Overlaying locale files completely, providing all translation keys.

  2. Merging the default locale file with a custom file. The default file will be merged with the custom file, with the keys in the custom file taking precedence.

Add more languages

Default provided languages are English and Swedish. Language files must be present in <overlay_dir>/assets/locales/ E.g. assets/locales/en.json

To add more languages add to the array in supportedLanguages and place file (using overlay method) in locales folder. E.g. add the following to the supportedLanguages array {code: 'de', name: 'Deutsch'} and add a file called assets/locales/de.json

Custom translation keys

To customize translations the files can be overlayed to specify different complete file with all translation keys, or use localesMergePath to extend and merge with the provided default files.

Useful when overriding specific translation keys only, and not having to provide all translation keys.

If one single file is used for multiple authenticators/applications, where you define all strings to be overridden in the same file, you can either 1. use the same overlay_dir for all authenticators/applications, or, 2. use /authn/assets/locales/ and overlay there.

Exemple of custom extension/merge:

Default language file contains the translations keys

{
    "selector.header": "Choose authentication method",
    "selector.error": "An error occured",
    "change_language": ""
}

The overlay_dir contains a ui_config_overrides.json with localesMergePath: "assets/custom_locales/" (see ui_config_overrides above)

A file is placed in <overlay_dir>/assets/custom_locales/en.json containing the following:

{
    "selector.header": "A different header"
}

The resulting merged language file used in the application will contain the following:

{
    "selector.header": "A different header",
    "selector.error": "An error occured",
    "change_language": ""
}

For each language that will be customized, add language files <overlay_dir>/assets/custom_locales/<lang>.json