Como personalizar a identidade visual do GLPI com o módulo Branding

Branding no GLPI que sobrevive à atualização: por que editar o core apaga a marca no update, o DOM real da tela de login no GLPI 11 (span.glpi-logo, body.welcome-anonymous), o CSS que o módulo injeta por hook, SQL de auditoria e as armadilhas de campo.

Trocar a logo do GLPI parece um ajuste de cinco minutos - até a próxima atualização apagar tudo. Personalizar a identidade visual editando o CSS do core ou o template de login funciona no dia, mas é uma dívida que vence sozinha: some no update e, no salto do GLPI 10 para o 11, o DOM da tela de login mudou de nome, então o hack antigo para de aplicar sem lançar erro nenhum. Este guia mostra como fazer branding que sobrevive à atualização, onde cada peça vive no GLPI 11 e as armadilhas que só aparecem em ambiente de cliente.

Branding no GLPI não é só estética

Um GLPI com a cara da organização reduz atrito: o usuário final reconhece que aquilo é o Service Desk da empresa, e não um sistema estranho pedindo login. Mas o custo escondido não está em escolher a cor certa - está em como a customização é aplicada. Existem três caminhos, e dois deles cobram caro depois.

  • Editar o core (CSS, imagens ou templates dentro de glpi/css, glpi/pics ou templates/): funciona, mas o próximo git pull ou o descompactar do release sobrescreve os arquivos. A personalização evapora e ninguém lembra por quê.
  • Tema/CSS injetado por fora: sobrevive ao update dos arquivos, mas fica preso aos seletores da versão. Quando o GLPI muda a estrutura HTML - como fez do 10 para o 11 - o seletor deixa de existir e o CSS vira letra morta, silenciosamente.
  • Hook de plugin: o GLPI expõe pontos de injeção oficiais (display_login, add_javascript). O módulo aplica a marca por esses hooks, sem tocar em um único arquivo do core. É o único caminho que sobrevive à atualização por design.

O que dá para personalizar - e onde cada peça vive

Cada elemento visual do GLPI mora em um lugar diferente do DOM, e trocar sem saber o alvo certo é o que gera a maioria dos chamados de "mudei e não apareceu". A matriz abaixo mapeia cada peça à sua chave de configuração e ao mecanismo real no GLPI 11:

PeçaChave de configMecanismo no GLPI 11Armadilha comum
Faviconfavicon_picture<link rel="icon"> reescrito via JSCache agressivo do navegador segura o ícone antigo
Título da abapage_titledocument.titleTelas que definem o próprio título revertem
Logo do loginlogin_picturespan.glpi-logo via content: url(...)Mirar .login-logo, que não existe no 11
Fundo do loginlogin_backgroundbody.welcome-anonymous / .page-anonymousMirar body.login-page, que não existe no 11
Logo do cabeçalhointernal_pictureHeader interno via add_javascriptConfundir com o logo de login (são alvos distintos)
Rodapéfooter_mode / footer_text.copyright (tema padrão do 11)Colar HTML não sanitizado no texto customizado
Cores da interfacecolor_*Variáveis CSS Tabler (--tblr-*)Passar valor que não é hex e injetar CSS quebrado

A armadilha do GLPI 11: o logo de login não é background

Na sustentação de ambientes de clientes, o chamado clássico é: "atualizamos o GLPI e a tela de login voltou ao padrão". Quase sempre a causa é uma customização feita direto no core ou num CSS que mirava os seletores do GLPI 10. No salto para o 11, o template da tela de login (page_card_notlogged.html.twig) foi reescrito: o <body> virou body.welcome-anonymous, o container virou .page-anonymous e o logo deixou de ser uma imagem de fundo - agora é um <span class="glpi-logo"> renderizado por content: var(--logo). Descobrimos isso na prática em 2026-06-10, depurando por que o fundo de login de um cliente simplesmente não aplicava após o upgrade: o seletor antigo body.login-page não existia mais no DOM. Não havia erro no log - o CSS estava correto para uma versão que não rodava mais. Por isso passamos a emitir os seletores certos por hook, versionados junto do módulo. Este é o CSS real que o módulo injeta - e os seletores mortos que explicam o sumiço:

/* GLPI 11 - seletores REAIS da tela de login (page_card_notlogged.html.twig) */
/* O logo NAO e background: e um <span class="glpi-logo"> com content: var(--logo) */
.page-anonymous .glpi-logo {
  content: url("/plugins/nextool/front/module_assets.php?module=branding&file=...") !important;
  width: 240px !important;
  height: 130px !important;
  object-fit: contain !important;   /* preserva a proporcao da imagem */
}

/* O fundo vai no body.welcome-anonymous / .page-anonymous - NUNCA em body.login-page */
body.welcome-anonymous,
.page-anonymous {
  background-image: url("...") !important;
  background-size: cover !important;
  background-position: center center !important;
}

/* Seletores do GLPI 10 que NAO existem mais no 11 (por isso o hack antigo some sem erro):
   .login-logo      -> agora e span.glpi-logo
   body.login-page  -> agora e body.welcome-anonymous  */

Como o módulo aplica sem tocar no core

Na tela de login não há sessão, então o módulo se pendura no hook display_login e injeta um bloco <style>/<script> inline. As imagens (favicon, logo, fundo) são servidas por um endpoint stateless que não exige login, com três proteções que valem citar porque são onde plugins descuidados vazam: a extensão passa por uma whitelist (png, jpg, jpeg, gif, ico, svg, webp), o caminho é resolvido com realpath() e conferido contra o prefixo do diretório de upload (bloqueio de path traversal), e o arquivo é gravado com nome único via uniqid() para não colidir nem sobrescrever. Nas páginas internas, já autenticadas, a customização entra pelo hook add_javascript.

Um detalhe de performance que só aparece medindo: o JS interno vai com Cache-Control: private, max-age=86400 e as imagens com public, max-age=604800 (uma semana), mas sem ETag. A razão é concreta - com ETag e max-age juntos, o Chrome revalidava (HTTP 304) a cada carregamento de página, e cada 304 ainda pagava o bootstrap completo do GLPI no servidor. Um hash da configuração entra no parâmetro fv= da URL, então salvar a config muda a URL e invalida o cache na hora, sem precisar de revalidação.

Configuração em cinco passos

  1. Ative o módulo Branding no catálogo de módulos do NexTool.
  2. Na aba Configurações, envie o favicon, a logo de login e a logo do cabeçalho; defina largura e altura de cada logo (aceita px, em, rem, %, vw, vh).
  3. Envie o fundo da tela de login e ajuste o título da aba do navegador.
  4. Escolha o comportamento do rodapé: manter o original, ocultar ou substituir por texto (HTML limitado a tags seguras).
  5. Opcional: defina as cores da interface por variáveis CSS (o módulo valida cada valor como hex antes de emitir, evitando CSS injection). Recarregue o GLPI para ver o resultado.

Auditoria: quem mudou o quê

Toda ação - ativar, desativar, salvar config, enviar ou apagar imagem - é gravada em uma tabela de log do módulo. Em ambiente com mais de um administrador, essa trilha responde "quem trocou a logo na sexta à noite" sem depender de memória. A consulta de diagnóstico:

-- Trilha de auditoria do modulo Branding: quem mudou a identidade visual e quando
SELECT l.date_creation  AS quando,
       u.name           AS usuario,
       l.action         AS acao,     -- save_config, upload_picture, delete_picture, toggle_enable/disable
       l.detail         AS detalhe
FROM   glpi_plugin_nextool_branding_log l
LEFT   JOIN glpi_users u ON u.id = l.users_id
ORDER  BY l.date_creation DESC
LIMIT  20;

Armadilhas de campo

  • Favicon que não troca - o navegador cacheia favicon de forma agressiva, por aba e por sessão. Depois de subir o novo ícone, um hard refresh (Ctrl+Shift+R) ou fechar e reabrir a aba resolve; não é bug do módulo.
  • SVG de fonte confiável - SVG é ótimo para logo (escala sem perder nitidez), mas pode carregar script embutido. Use SVG apenas de arte que você mesmo gerou; o endpoint serve o arquivo com o Content-Type correto, mas a higiene começa no upload.
  • Rodapé com HTML colado - o texto customizado do rodapé passa por sanitização que só permite um punhado de tags (a, b, strong, i, em, span, br). Colar um bloco inteiro de HTML de marketing simplesmente não renderiza o que você espera.
  • Proporção da logo - definir largura e altura fixas sem respeitar a proporção original distorce a imagem. O módulo aplica object-fit: contain justamente para não esticar, mas vale conferir na tela.
  • Upgrade 10 para 11 - se o cliente já tinha branding manual no GLPI 10, ele vai sumir no 11 pelos seletores trocados. Trate o branding como parte do plano de upgrade, não como surpresa pós-migração.

Quer padronizar a identidade visual do GLPI em todos os ambientes que você administra, sem reabrir o assunto a cada atualização? O módulo Branding é gratuito e aplica a marca por hooks nativos. E, se preferir terceirizar a implantação e a sustentação do GLPI, a NexTool mantém ambientes de clientes com branding versionado e à prova de update.


Este conteúdo foi produzido com auxílio de inteligência artificial e revisado pela equipe Nextool Solutions.

Perguntas Frequentes

Porque a customização foi feita direto no core (arquivos de CSS, imagens ou templates), e o update do GLPI sobrescreve esses arquivos. A forma de sobreviver à atualização é aplicar a marca por hooks de plugin (display_login, add_javascript), sem tocar no core - foi para isso que o módulo Branding existe.

No GLPI 11 o template da tela de login foi reescrito. O logo deixou de ser imagem de fundo e virou um <span class="glpi-logo"> com content: var(--logo); o body virou body.welcome-anonymous e o container .page-anonymous. Se o CSS mira os seletores do GLPI 10 (.login-logo, body.login-page), eles não existem mais no DOM e a regra não aplica, sem lançar erro.

Não. O módulo Branding aplica favicon, logos, fundo de login, rodapé e cores pela interface, via hooks nativos. As alterações não ficam em arquivos do core, então sobrevivem à atualização do GLPI.

Na aba Configurações do módulo, envie a imagem do favicon e digite o título desejado. O módulo reescreve o <link rel="icon"> e o document.title por JavaScript. Se o ícone novo não aparecer, é cache do navegador: um hard refresh (Ctrl+Shift+R) ou reabrir a aba resolve.

Sim, SVG é aceito e escala sem perder nitidez. O upload passa por whitelist de extensão e o serviço protege contra path traversal. Como SVG pode conter script embutido, use apenas arte de fonte confiável (idealmente gerada por você), não arquivos de origem desconhecida.

Sim. O Branding é gratuito, faz parte do NexTool e é compatível com GLPI 10 e 11. Atenção no upgrade: se havia branding manual no 10, ele não migra sozinho para o 11 (os seletores da tela de login mudaram); reaplique pelo módulo após a migração.

Precisa de ajuda?