Company branding setup#
Configuring branding.json in Sherpa AI Server#
Purpose#
The branding.json file lets you change the appearance and part of the behavior of the Sherpa AI Server interface without rebuilding the frontend:
- name and logos;
- main colors, border radius, and font;
- user and Assistant message backgrounds;
- default language and available languages;
- display of the OpenID sign-in button;
- additional links in the side menu;
- an information button on the sign-in page.
The settings are applied in the browser when the application loads. There is no separate branding administration screen in Sherpa AI Server.
Where the file is located#
In source code#
Main file:
frontend/src/assets/branding/branding.json
It is included in the frontend build and is used as the default settings set for the distribution.
In the client distribution#
When preparing the client archive, the file is copied here:
frontend/config/branding.json
To make nginx use this file, enable a bind mount in the docker-compose.yml file for the aiserver-nginx service:
services:
aiserver-nginx:
volumes:
- ./frontend/config/branding.json:/opt/SherpaAIServer/frontend/dist/assets/branding/branding.json:ro
In the distributed docker-compose.yml, this line may be commented out. After enabling the mount for the first time, recreate the container:
docker compose up -d --force-recreate aiserver-nginx
If the mount is already enabled, changes to the file on the host are visible inside the container immediately. Reloading the page is enough to apply them in the interface.
How the configuration is loaded#
When the frontend starts, it requests:
/assets/branding/branding.json
The configuration is loaded before the Angular application starts. Because of that, the language, logos, and branding CSS variables are available during the initial rendering of the interface.
Loading rules:
- Built-in Sherpa AI Server values are used as the base.
- Fields from
branding.jsonreplace the corresponding built-in values. - If the file is unavailable or contains invalid JSON, the application continues to work with the built-in values.
- Missing top-level fields do not need to be specified: the built-in values are preserved for them.
- Nested objects and array items are not filled in automatically — they must be set in full.
The _comments field inside the standard branding.json file contains reference descriptions. This is a normal JSON helper field; the interface does not use it.
Quick start#
Copy or edit
frontend/config/branding.json.Make sure the bind mount is enabled in
docker-compose.yml.Check the JSON syntax:
jq empty frontend/config/branding.jsonWhen connecting the file for the first time, recreate
aiserver-nginx:docker compose up -d --force-recreate aiserver-nginxCheck which file the server is serving:
curl -fsS https://<server-address>/assets/branding/branding.json | jq .Reload the Sherpa AI Server page. If the browser shows stale resources, perform a hard refresh.
Complete example#
{
"app_name": "Корпоративный AI",
"logo_url": "assets/branding/logo-light-v1.svg",
"logo_url_light": "assets/branding/logo-light-v1.svg",
"logo_url_dark": "assets/branding/logo-dark-v1.svg",
"disable_openid": false,
"default_language": "ru",
"available_languages": ["ru", "en"],
"additional_menu_items": [
{
"button_name": {
"ru": "Поддержка",
"en": "Support"
},
"url": "https://support.example.org",
"icon": "question-mark-circle-outline"
},
{
"button_name": {
"ru": "Инструкции",
"en": "Documentation"
},
"url": "/main/documents",
"icon": "book-open-outline"
}
],
"additional_login_button": {
"button_name": {
"ru": "Как получить доступ?",
"en": "How do I get access?"
},
"message": {
"ru": "Для получения доступа обратитесь в службу поддержки.",
"en": "Contact the support team to request access."
}
},
"primary_color": "#2563eb",
"primary_dark_color": "#1d4ed8",
"primary_light_color": "#60a5fa",
"primary_rgb": "37, 99, 235",
"secondary_color": "#1f2937",
"border_radius": "8px",
"font_family": "Inter, sans-serif",
"font_url": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap",
"chat_user_bg": "#eff6ff",
"chat_assistant_bg": "#ffffff"
}
Parameter descriptions#
| Parameter | Format | Purpose |
|---|---|---|
app_name |
string | Name next to the logo in the side menu and the logo alt text. It does not change the sign-in card title or the page <title> — Sherpa AI Server is currently used there. |
logo_url |
URL string | Fallback logo for compatibility. Used if a separate logo for the required theme is not set. |
logo_url_light |
URL string | Logo for the light theme. |
logo_url_dark |
URL string | Logo for the dark theme. |
disable_openid |
true or false |
When true, hides the Sign in with OpenID button on the sign-in page. The parameter controls the interface and by itself does not disable OpenID on the backend. |
default_language |
ru or en |
Default language. The value must be present in available_languages. |
available_languages |
array of ru and/or en |
Languages available to the user. Other values are discarded. |
additional_menu_items |
array of objects | Additional permanent items in the side menu before the Chat section. |
additional_login_button |
object or null |
Information button on the sign-in page. Clicking it opens a dialog with localized text. null hides the button. |
primary_color |
#RRGGBB |
Main color for buttons, links, active elements, tables, and form controls. |
primary_dark_color |
#RRGGBB |
Darker shade of the main color for hover and press states and some switches. |
primary_light_color |
#RRGGBB |
Lighter shade for highlights and secondary states. |
primary_rgb |
R, G, B string |
RGB components of primary_color for translucent backgrounds, shadows, and highlights. |
secondary_color |
CSS color | Secondary color. It is also used for card surfaces in the dark theme and the splash screen. |
border_radius |
CSS size | Element rounding, for example 0px, 6px, or 16px. |
font_family |
CSS font-family |
Font family applied to the interface. |
font_url |
CSS file URL | Stylesheet from which the browser loads the font. An empty string disables the extra download. |
chat_user_bg |
CSS color | Background of user messages on the Chat screen. |
chat_assistant_bg |
CSS color | Background of Assistant responses on the Chat screen. |
Configuring logos#
Logo selection priority for each theme:
logo_url_light or logo_url_dark → logo_url → built-in logo
You can use:
- a relative path inside the frontend, for example
assets/branding/logo-light-v1.svg; - an absolute path from the site root, for example
/assets/branding/logo-light-v1.svg; - an absolute URL, for example
https://static.example.org/logo-light-v1.svg.
If the logo is stored alongside the client configuration, mount it separately in docker-compose.yml:
services:
aiserver-nginx:
volumes:
- ./frontend/config/branding.json:/opt/SherpaAIServer/frontend/dist/assets/branding/branding.json:ro
- ./frontend/config/logo-light-v1.svg:/opt/SherpaAIServer/frontend/dist/assets/branding/logo-light-v1.svg:ro
- ./frontend/config/logo-dark-v1.svg:/opt/SherpaAIServer/frontend/dist/assets/branding/logo-dark-v1.svg:ro
In production, images, fonts, and other static files can be cached by the browser for up to a year. When the logo content changes, use a new name, for example logo-light-v2.svg, and update the path in branding.json.
Configuring colors#
primary_color and primary_rgb describe the same color in different formats. They are not synchronized automatically.
Example:
{
"primary_color": "#2563eb",
"primary_rgb": "37, 99, 235"
}
For primary_color, primary_dark_color, and primary_light_color, use the full #RRGGBB HEX format. The service calculates the contrast of the main color for text and icons, so shortened HEX and rgb(...) or rgba(...) values should not be used for these three fields.
For secondary_color, chat_user_bg, and chat_assistant_bg, regular CSS colors such as HEX or rgba(...) are allowed.
After changing colors, check both themes, tables, form fields, buttons, and the readability of chat messages.
Configuring the font#
font_url must point to a CSS file with the font, and font_family must point to the family name from that CSS file:
{
"font_family": "Inter, sans-serif",
"font_url": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
}
For a custom font, you can mount the CSS and font files into the frontend directory and use a relative URL. Make sure the URL is accessible from the users' browsers, not only from the Sherpa AI Server backend.
To avoid loading an extra CSS file, leave font_url empty:
{
"font_family": "Roboto, 'Helvetica Neue', sans-serif",
"font_url": ""
}
Interface languages#
Only ru and en values are supported.
If available_languages is empty, has an invalid format, or does not contain supported values, Sherpa AI Server enables both languages. If default_language is missing from the available languages list, the first available_languages item becomes the default language.
Example of an interface in Russian only:
{
"default_language": "ru",
"available_languages": ["ru"]
}
The current-language button remains visible, but the switcher menu does not open.
The actual language is selected in the following order:
- the
langorlocaleparameter in the URL; - the previously selected browser language;
default_languagefrombranding.json.
The value from the URL or browser is applied only when the language is present in available_languages.
Additional menu items#
Each additional_menu_items entry must contain:
{
"button_name": {
"ru": "Поддержка",
"en": "Support"
},
"url": "https://support.example.org",
"icon": "question-mark-circle-outline"
}
Rules:
- at least one non-empty translation of the name is required;
urlmust be an internal path with a single leading/or a URL with thehttporhttpsprotocol;- values with other protocols and invalid URLs are ignored;
- internal links open through the Sherpa AI Server router;
- external links open in the current tab;
- items are displayed in the same order as in the array;
- for a standard icon, specify an Eva Icons name, for example
book-open-outline; - a string ending in
/or.svgis treated as a path to a custom SVG icon.
If a translation is missing, Russian is used first, then English.
Information button on the sign-in page#
Example:
{
"additional_login_button": {
"button_name": {
"ru": "Forgot your password?",
"en": "Forgot your password?"
},
"message": {
"ru": "Contact the support team.",
"en": "Contact the support team."
}
}
}
The button is shown if at least one name and at least one message text are filled in. The text is displayed as plain text, not HTML. If a translation is missing, Russian is used first, then English.
To hide the button:
{
"additional_login_button": null
}