Configuração da marca da empresa#

Configurando branding.json no Sherpa AI Server#

Finalidade#

O arquivo branding.json permite alterar a aparência e parte do comportamento da interface do Sherpa AI Server sem recompilar o frontend:

  • nome e logotipos;
  • cores principais, raio dos cantos e fonte;
  • plano de fundo das mensagens do usuário e do Assistente;
  • idioma padrão e idiomas disponíveis;
  • exibição do botão de login com OpenID;
  • links adicionais no menu lateral;
  • um botão de informação na página de login.

As configurações são aplicadas no navegador quando a aplicação é carregada. Não existe uma tela separada de administração de branding no Sherpa AI Server.

Onde o arquivo fica#

No código-fonte#

Arquivo principal:

frontend/src/assets/branding/branding.json

Ele faz parte da build do frontend e é usado como o conjunto padrão de configurações para a distribuição.

Na distribuição do cliente#

Ao preparar o pacote do cliente, o arquivo é copiado para este local:

frontend/config/branding.json

Para que o nginx use este arquivo, é necessário habilitar um bind mount no docker-compose.yml no serviço aiserver-nginx:

services:
  aiserver-nginx:
    volumes:
      - ./frontend/config/branding.json:/opt/SherpaAIServer/frontend/dist/assets/branding/branding.json:ro

No docker-compose.yml distribuído, essa linha pode estar comentada. Depois de habilitar o mount pela primeira vez, recrie o contêiner:

docker compose up -d --force-recreate aiserver-nginx

Se o mount já estiver habilitado, as alterações no arquivo do host ficam visíveis imediatamente dentro do contêiner. Para aplicá-las na interface, basta recarregar a página.

Como a configuração é carregada#

Quando o frontend inicia, ele solicita:

/assets/branding/branding.json

A configuração é carregada antes da inicialização do aplicativo Angular. Por isso, o idioma, os logotipos e as variáveis CSS de branding já estão disponíveis durante a renderização inicial da interface.

Regras de carregamento:

  1. Os valores embutidos do Sherpa AI Server são usados como base.
  2. Os campos de branding.json substituem os valores embutidos correspondentes.
  3. Se o arquivo não estiver disponível ou contiver JSON inválido, a aplicação continua funcionando com os valores embutidos.
  4. Os campos de nível superior ausentes não precisam ser informados: os valores embutidos são mantidos para eles.
  5. Objetos aninhados e itens de arrays não são preenchidos automaticamente — eles devem ser definidos por completo.

O campo _comments dentro do branding.json padrão contém descrições de referência. É um campo auxiliar normal de JSON; a interface não o utiliza.

Início rápido#

  1. Copie ou edite frontend/config/branding.json.

  2. Verifique se o bind mount está habilitado em docker-compose.yml.

  3. Confira a sintaxe do JSON:

    jq empty frontend/config/branding.json
    
  4. Ao conectar o arquivo pela primeira vez, recrie o aiserver-nginx:

    docker compose up -d --force-recreate aiserver-nginx
    
  5. Verifique qual arquivo o servidor está fornecendo:

    curl -fsS https://<server-address>/assets/branding/branding.json | jq .
    
  6. Recarregue a página do Sherpa AI Server. Se o navegador mostrar recursos antigos, faça um hard refresh.

Exemplo completo#

{
  "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"
}

Descrição dos parâmetros#

Parâmetro Formato Finalidade
app_name string Nome ao lado do logotipo no menu lateral e texto alt do logotipo. Não altera o título do cartão de login nem o <title> da página — atualmente Sherpa AI Server é usado ali.
logo_url string de URL Logotipo de fallback por compatibilidade. Usado se um logotipo separado para o tema necessário não estiver definido.
logo_url_light string de URL Logotipo para o tema claro.
logo_url_dark string de URL Logotipo para o tema escuro.
disable_openid true ou false Quando true, oculta o botão Entrar com OpenID na página de login. O parâmetro controla a interface e, por si só, não desativa o OpenID no backend.
default_language ru ou en Idioma padrão. O valor deve estar presente em available_languages.
available_languages array de ru e/ou en Idiomas disponíveis para o usuário. Outros valores são descartados.
additional_menu_items array de objetos Itens permanentes adicionais no menu lateral antes da seção Chat.
additional_login_button objeto ou null Botão de informação na página de login. Ao clicar, abre uma caixa de diálogo com texto localizado. null oculta o botão.
primary_color #RRGGBB Cor principal para botões, links, elementos ativos, tabelas e controles de formulário.
primary_dark_color #RRGGBB Tom mais escuro da cor principal para estados de hover e pressionado e alguns seletores.
primary_light_color #RRGGBB Tom mais claro para realces e estados secundários.
primary_rgb string R, G, B Componentes RGB de primary_color para fundos translúcidos, sombras e realces.
secondary_color cor CSS Cor secundária. Também é usada nas superfícies dos cartões no tema escuro e na tela de abertura.
border_radius tamanho CSS Arredondamento dos elementos, por exemplo 0px, 6px ou 16px.
font_family font-family CSS Família de fonte aplicada à interface.
font_url URL de arquivo CSS Folha de estilo da qual o navegador carrega a fonte. Uma string vazia desativa o download adicional.
chat_user_bg cor CSS Fundo das mensagens do usuário na tela Chat.
chat_assistant_bg cor CSS Fundo das respostas do Assistente na tela Chat.

Configuração dos logotipos#

Prioridade de seleção do logotipo para cada tema:

logo_url_light or logo_url_dark → logo_url → built-in logo

É possível usar:

  • um caminho relativo dentro do frontend, por exemplo assets/branding/logo-light-v1.svg;
  • um caminho absoluto a partir da raiz do site, por exemplo /assets/branding/logo-light-v1.svg;
  • uma URL absoluta, por exemplo https://static.example.org/logo-light-v1.svg.

Se o logotipo estiver armazenado junto com a configuração do cliente, monte-o separadamente em 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

Em produção, imagens, fontes e outros arquivos estáticos podem ser armazenados em cache pelo navegador por até um ano. Quando o conteúdo do logotipo mudar, use um novo nome, por exemplo logo-light-v2.svg, e atualize o caminho em branding.json.

Configuração das cores#

primary_color e primary_rgb descrevem a mesma cor em formatos diferentes. Eles não são sincronizados automaticamente.

Exemplo:

{
  "primary_color": "#2563eb",
  "primary_rgb": "37, 99, 235"
}

Para primary_color, primary_dark_color e primary_light_color, use o formato HEX completo #RRGGBB. O serviço calcula o contraste da cor principal para o texto e os ícones, portanto não se deve usar HEX abreviado nem valores rgb(...) ou rgba(...) para esses três campos.

Para secondary_color, chat_user_bg e chat_assistant_bg, cores CSS normais, como HEX ou rgba(...), são permitidas.

Depois de alterar as cores, verifique os dois temas, tabelas, campos de formulário, botões e a legibilidade das mensagens no chat.

Configuração da fonte#

font_url deve apontar para um arquivo CSS com a fonte, e font_family deve apontar para o nome da família nesse arquivo CSS:

{
  "font_family": "Inter, sans-serif",
  "font_url": "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
}

Para uma fonte personalizada, é possível montar o CSS e os arquivos da fonte no diretório frontend e usar uma URL relativa. Certifique-se de que a URL esteja acessível nos navegadores dos usuários, e não apenas no backend do Sherpa AI Server.

Para não carregar um arquivo CSS adicional, deixe font_url vazio:

{
  "font_family": "Roboto, 'Helvetica Neue', sans-serif",
  "font_url": ""
}

Idiomas da interface#

Somente os valores ru e en são suportados.

Se available_languages estiver vazio, tiver um formato inválido ou não contiver valores suportados, o Sherpa AI Server habilita os dois idiomas. Se default_language não estiver presente na lista de idiomas disponíveis, o primeiro item de available_languages se torna o idioma padrão.

Exemplo de uma interface somente em russo:

{
  "default_language": "ru",
  "available_languages": ["ru"]
}

O botão do idioma atual continua visível, mas o menu de troca não é aberto.

O idioma real é selecionado na seguinte ordem:

  1. o parâmetro lang ou locale na URL;
  2. o idioma escolhido anteriormente no navegador;
  3. default_language de branding.json.

O valor da URL ou do navegador só é aplicado quando o idioma está presente em available_languages.

Itens adicionais do menu#

Cada item de additional_menu_items deve conter:

{
  "button_name": {
    "ru": "Поддержка",
    "en": "Support"
  },
  "url": "https://support.example.org",
  "icon": "question-mark-circle-outline"
}

Regras:

  • pelo menos uma tradução não vazia do nome é necessária;
  • url deve ser um caminho interno com apenas uma / inicial ou uma URL com o protocolo http ou https;
  • valores com outros protocolos e URLs inválidas são ignorados;
  • links internos são abertos pelo roteador do Sherpa AI Server;
  • links externos são abertos na aba atual;
  • os itens são exibidos na mesma ordem em que aparecem no array;
  • para um ícone padrão, informe um nome de Eva Icons, por exemplo book-open-outline;
  • uma string que termine em / ou .svg é interpretada como um caminho para um ícone SVG personalizado.

Se faltar uma tradução, primeiro é usado o russo e depois o inglês.

Botão de informação na página de login#

Exemplo:

{
  "additional_login_button": {
    "button_name": {
      "ru": "Forgot your password?",
      "en": "Forgot your password?"
    },
    "message": {
      "ru": "Contact the support team.",
      "en": "Contact the support team."
    }
  }
}

O botão é exibido se houver pelo menos um nome e pelo menos um texto de mensagem preenchidos. O texto é exibido como texto simples, não como HTML. Se faltar uma tradução, primeiro é usado o russo e depois o inglês.

Para ocultar o botão:

{
  "additional_login_button": null
}