Application configuration

All applications created with the Web SDK are fully customizable through a custom build. We recommend you to leverage branding and configuration options without building the application, as this configuration can then be shared across multiple applications. This section will initially outline the “no-build option” before detailing how to customize a built application.

Application options

The easiest option to customize your application are application options. They apply to any Web SDK application and use inheritance which allows you to apply the same configurations to all your applications. One example configuration is hideNavigator, which is a simple flag that configures if the navigator must be shown on application start or not. You can configure this in 3 ways:

  1. as a URL parameter
  2. as a dynamic public option
  3. as a static private option

With regard to inheritance, the option “a URL parameter” contains the highest privilege, followed by the “dynamic public option” and the “static private option” respectively. Simply add a URL parameter to your application for testing out certain options. For example, to hide the navigator you would simply use the URL: apps/<<your-app-name>>/index.html?hideNavigator=true#/route. Note that the URL parameter needs to be set before the #-hash navigation.

The dynamic public option is requested by each Web SDK based application upon startup. The default fetch URL for this options is stored in the dynamicOptionsUrl which is by default set to "/apps/public/public-options/options.json". As you can see by the context-path, the default setting points to an application deployed to your tenant. To create this application on your own ceate a zip file called public-options.zip and add a options.json to it:

{
  hideNavigator: true
}

If you upload this application to your tenant and subscribe it to at least one of your subtenants, all Web SDK based applications hide the navigator by default.

Info
If you are an Enterprise tenant customer, the easiest way to manipulate this options is to use the branding manager in administration. It allows you to set most of the settings without the need to manually generate a JSON file and upload any applications.

The static private option can only be defined by a custom application. They are the lowest option level and can be overwritten by any of the upper options (1 and 2). They are also private, meaning they only apply to the current application they are applied to. You can define those options in the cumulocity.config.ts file by adding them to the runTime fragment:

[...]
export default {
  runTime: {
    [...]
    hideNavigator: true
  },
}
[...]

It is good practice to use the URL option in order to verify an option behavior, or to use the dynamic option in order to set the option platform wide (branding) and to use the private static option in order to set the default for your custom application.

To see all available options, refer to Styling with application options in the Cumulocity IoT Codex.

Branding your application

A branding must always be applied to all of your applications. Therefore, it is recommended to use dynamic public options for branding your application. You must set the right design tokens in the brandingCssVars application option. Those are CSS variables that get applied to all default style sheets of Cumulocity IoT and will show your custom branding for any Web SDK application. Your options.json then look like this:

{
  "brandingCssVars": {
    "--brand-primary": "#B10F2E",
    "--brand-complementary": "#DE7C5A",
    "--brand-dark": "#280000",
    "--brand-light": "#DE7C5A",
    "--palette-status-realtime" : "#f0f"
  }
}

You can add other options, for example, the hideNavigator or add your own CSS file:

{
  "brandingCssVars": {
    "--brand-primary": "#B10F2E",
    "--brand-complementary": "#DE7C5A",
    "--brand-dark": "#280000",
    "--brand-light": "#DE7C5A",
    "--palette-status-realtime" : "#f0f"
  },
  "hideNavigator": true,
  "extraCssUrls": "./custom.css",
}

In the CSS file you can add your own styles:

h1 {
  color: #00f;
}

Follow the steps below:

  1. Zip the files to ensure that they are in the root of the zip without any wrapping folder.
  2. Name the zip file public-options.zip.
  3. Upload it as a web application in Administration > Ecosystem > Applications.
  4. Subscribe your applications to one of your tenants under Tenants > Subtenants.

Afterwards, you can update the existing application with new variables in the detail view of the application.

Info
If you are an Enterprise tenant customer, the easiest way to manipulate this options is to use the branding manager in administration. It provides an form to set most of the settings without any manual generating of a JSON file and uploading applications.

Styling by extending @c8y/style

For styling the application global CSS created with LESS is used. The original LESS source is distributed via the npm package @c8y/style. By extending these styles it is possible to change any detail of the application but the vast majority of developers want to change: colors, logos and fonts and these can be very easily achieved by replacing a few variables.

To override variables, Custom CSS Properties—also known as CSS Variables—can be utilized, offering configurability at runtime or during the build process.

  1. Ensure that your project is based on the Angular CLI (whether upgraded or created from scratch).
  2. Make sure you have installed the @c8y/style package. If not, you can install the base styles from npm using the following command.
@import '~@c8y/style/main.less';

The example is based on this file structure:

my-application
|   ...
│   angular.json
│   package.json
|   ...
└───src
    │   styles.less
    │   favicon.ico
    │   ...
    └─── assets
         │   logo.jpg
         │   ...
  1. If styles.less already exists, add the line @import '~@c8y/style/main.less' at the top of the file. If it does not exist, create it and add the mentioned line. Also, include it in the styles entry in angular.json under your project entry.

  2. In the cumulocity.config.ts file, add brandingEntry: './src/styles.less' to the buildTime entry.

If you are using a different file from styles.less located in another location, please adjust the paths as described in the previous step. Ensure to correctly set both the brandingEntry and the styles entry in angular.json.

Example customizations

At this point, we can modify the desired variables to suit our needs. To implement these changes, follow the examples below and add the specified code to your styles.less file.

Let us change for example the most important color of your branding, the main color, called brand-primary.

This is done by setting the respective CSS variables to a new color.

:root {
  --brand-primary: red;
}

User interface elements like buttons, active navigation nodes or even active tabs as well as also hover-states of buttons are red now.

To change the brand logo you can use this:

:root {
  --brand-logo-img: url('/apps/<applicationContextPath>/assets/logo.jpg');
  --brand-logo-img-height: 48%;
}

The applicationContextPath can be any application that you uploaded to the platform and which contains the logo.jpg file.

Languages customization

The platform UI strings used for internationalization are stored in gettext. If you want to add a new language to the platform you need a software to edit these files, for example, Poedit.

Each translated catalog is loaded at runtime in a JSON format. To convert .po (gettext) files into .json files we rely on @angular/cli installed during the first step.

How to add your own translations at build time

  1. Download the string catalog from @c8y/ngx-components@1004.0.6/locales/locales.pot (starting from version 1004.0.6,latest can be replaced by your current used version).
  2. Load the downloaded locales.pot template file in your preferred .pot file editor and create a new translation from it. Select the target language of the translation, for example, Afrikaans, and translate each string. Repeat the process for as many languages as you like. The outcome of this step is a .po catalog file for each language. Make sure to store these files in a safe place, as they are useful when updating the strings in subsequent versions.
  3. Transform the newly created .po file into a .json file using the c8ycli:
c8ycli locale-compile path/to/language.po
  1. Copy the generated .json file into the ui-assets folder.
  2. Update the languages fragment in public-options/options.json.
languages?: {
  [langCode: string]: {
    name: string;
    nativeName: string;
    url: string;
  }
}

In the example provided in the repository, available as downloaded, you can find an example of a Ukrainian translation which looks like this:

[...]

export default {
  runTime: {
    [...]
    languages: {
      uk: {
        name: "Ukraine",
        nativeName: "українська",
        url: "/apps/public/ui-assets/uk.json"
      }
    }
  },
  buildTime: {
    [...]
  }
}
[...]

You can change the imported language in the UI after login. To do so, click the User icon at the top right, select User settings from the menu and in the upcoming window select the language of your choice.

How to add your own translations at runtime

You can translate certain strings at runtime, which means they do not have to be included in the build and can simply be added to the application options. However, this concept doesn’t allow to add new languages. You can only add new strings to existing languages or align certain translations on existing ones. To translate a certain key you must add the following structure to the application options:

  i18nExtra?: {
    [langCode: string]: {
      [key: string]: string;
    };
  };

Example:

The following will translate a custom cookie banner:

[...]

export default {
  runTime: {
    [...]
    i18nExtra: {
      de: {
        "About cookies on Cumulocity IoT": "Informationen zu Cookies in Cumulocity IoT",
        "Click Agree and Proceed to accept cookies and go directly to the platform or click on Privacy Policy to see detailed descriptions of the used cookies.": "Klicken Sie auf Zustimmen und fortfahren, um Cookies zu akzeptieren und direkt zur Plattform zu gelangen, oder klicken Sie auf Datenschutzrichtlinie, um detaillierte Beschreibungen der verwendeten Cookies anzuzeigen."
      }
    }
  },
  buildTime: {
    [...]
  }
}
[...]