CSS e JavaScript personalizados
Personalize o cabeçalho com logotipo e cores e adicione um botão flutuante Ask AI com CSS e JavaScript compatíveis com atualizações do Jamdesk.
Esta página monta um exemplo em um site de demonstração chamado Harbor. O cabeçalho recebe o logotipo, as cores e dois links adicionais do Harbor, e um botão flutuante Ask AI fica no canto inferior direito. Você pode copiar os arquivos como estão e, depois, inserir seu próprio logotipo e suas cores.
As capturas de tela mostram a interface em inglês.

O que muda neste cabeçalho
Por padrão, o cabeçalho do tema Jam se mistura à página. No modo claro, é transparente e exibe o gradiente suave ao fundo; no modo escuro, tem o mesmo tom quase preto de todo o restante. Os botões têm cantos levemente arredondados. A versão do Harbor muda quatro coisas:
- É uma barra azul-marinho nos modos claro e escuro, destacando-se da página.
- Uma linha laranja fina percorre a borda inferior.
- A caixa de pesquisa, Ask AI e Book a demo têm formato de pílula.
- O logotipo branco do Harbor substitui o logotipo padrão.
As alterações consistem em CSS e um arquivo de logotipo. O próprio cabeçalho do Jamdesk não é alterado, então a pesquisa, o Ask AI, a troca de tema e o menu para dispositivos móveis continuam funcionando como antes.
O exemplo usa estes arquivos no seu projeto:
harbor-docs/
├── docs.json ← logo, header links and brand colors
├── style.css ← header and button styles
├── script.js ← creates the Ask AI button
└── images/
└── harbor-logo.svg ← white logo for the navy header
Comece com docs.json
A primeira parte não exige código. O logotipo, as cores, os links do cabeçalho e o botão Book a demo ficam todos em docs.json:
{
"logo": {
"light": "/images/harbor-logo.svg",
"dark": "/images/harbor-logo.svg"
},
"colors": {
"primary": "#C2410C",
"light": "#D9480F",
"dark": "#9A3412"
},
"navbar": {
"links": [
{ "label": "Blog", "href": "https://example.com/blog" },
{ "label": "Status", "href": "https://example.com/status" }
],
"primary": {
"type": "button",
"label": "Book a demo",
"href": "https://example.com/demo"
}
}
}O logotipo é branco. Como o cabeçalho é azul-marinho nos modos claro e escuro, o mesmo arquivo serve para ambos.
O Jamdesk usa sua cor primary no botão Book a demo, no item ativo da barra lateral e nos links, para que o laranja apareça em todo o site. No modo escuro, usa a cor light. Escolha um tom escuro o suficiente para que o texto branco no botão continue fácil de ler. Consulte Links de navegação para ver todas as opções da barra de navegação.
Os links da barra de navegação aparecem no cabeçalho em telas de tablet e desktop nos temas que posicionam o logotipo no cabeçalho (Jam, Nebula, Halo e Dusk). Em celulares, eles passam para o menu, então os estilos de cabeçalho abaixo não se aplicam a eles. O Pulsar posiciona o logotipo na barra lateral e não tem uma barra de cabeçalho no desktop, portanto os estilos de cabeçalho abaixo não serão exibidos nele.
Estilize o cabeçalho
O texto, as bordas, a caixa de pesquisa e o arredondamento dos cantos do cabeçalho são definidos por variáveis CSS. Se você definir essas variáveis dentro do cabeçalho, somente ele será alterado:
/* header[data-has-tabs] matches the site header only.
A plain `header` selector would also match the title
block at the top of every page. */
header[data-has-tabs] {
--header-top: #0f1d3a;
--header-bottom: #1b2f5b;
--header-stripe: #f97316;
--color-text-primary: #ffffff;
--color-text-secondary: #cbd5e1;
--color-text-tertiary: #cbd5e1;
--color-text-muted: #94a3b8;
--color-bg-primary: #0f1d3a;
--color-bg-secondary: rgba(255, 255, 255, 0.08);
--color-bg-hover: rgba(255, 255, 255, 0.16);
--color-border: rgba(255, 255, 255, 0.16);
/* Rounds the search box, Ask AI and buttons into pills */
--radius-md: 999px;
--radius-lg: 999px;
}
html.dark header[data-has-tabs] {
--header-top: #0a1328;
--header-bottom: #13234a;
--color-bg-primary: #0a1328;
}
/* Some themes keep the header background transparent on
purpose, so paint the color on a layer behind it. */
header[data-has-tabs]::before {
content: "";
position: absolute;
inset: 0 -24px; /* reach past the 16-24px page gutter */
z-index: -1;
background: linear-gradient(
90deg, var(--header-top), var(--header-bottom)
);
border-bottom: 3px solid var(--header-stripe);
}
/* The sparkle icon uses the accent color, which is hard to
see on navy, so give it the stripe color instead */
header[data-has-tabs] .fa-sparkles {
color: #fdba74;
}O azul-marinho fica em uma camada ::before porque o tema Jam define o background do cabeçalho como none com !important. Uma regra background comum no cabeçalho não prevaleceria. A camada fica atrás do conteúdo do cabeçalho e funciona em todos os temas.
Definir --radius-md e --radius-lg como 999px transforma os botões do cabeçalho em pílulas. A alteração fica dentro de header[data-has-tabs], então os cartões e blocos de código da página mantêm os cantos habituais.
O ícone Ask AI no cabeçalho usa a cor de destaque, que é difícil de ver sobre o azul-marinho. A última regra o deixa laranja-claro.
No modo escuro, o Jamdesk adiciona a classe dark a <html>, então o bloco html.dark deixa o azul-marinho um pouco mais escuro:

Adicione um botão flutuante Ask AI
Seu script adiciona um <button> comum à página. Ao clicar nele, é enviado Ctrl+I, o atalho de teclado que abre e fecha o painel de chat, fazendo o mesmo que o botão Ask AI no cabeçalho.
(function () {
if (document.getElementById('ask-ai-fab')) return;
var button = document.createElement('button');
button.id = 'ask-ai-fab';
button.type = 'button';
// Jamdesk loads Font Awesome, so its icons are available here
var icon = document.createElement('i');
icon.className = 'fa-solid fa-sparkles';
icon.setAttribute('aria-hidden', 'true');
button.append(icon, ' Ask AI');
button.addEventListener('click', function () {
// Same as pressing Ctrl+I / Cmd+I: toggles the chat panel
var shortcut = { key: 'i', ctrlKey: true, bubbles: true };
document.dispatchEvent(new KeyboardEvent('keydown', shortcut));
});
document.body.appendChild(button);
})();Depois, adicione os estilos do botão a style.css:
#ask-ai-fab {
position: fixed;
right: 24px;
bottom: 24px;
z-index: 40; /* below the header, search and mobile menu */
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 18px;
border: 0;
border-radius: 999px;
background: #c2410c;
color: #fff;
font: inherit;
font-weight: 600;
box-shadow: 0 6px 20px rgba(15, 29, 58, 0.25);
cursor: pointer;
}
#ask-ai-fab:hover {
background: #9a3412;
}
#ask-ai-fab:focus-visible {
outline: 2px solid #f97316;
outline-offset: 2px;
}
/* Hide the button while the chat panel is open. On mobile
the closed panel stays in the page with data-open="false",
so exclude that case. */
body:has([data-chat-panel]:not([data-open="false"])) #ask-ai-fab {
display: none;
}
@media (max-width: 767px) {
#ask-ai-fab {
right: 16px;
bottom: 16px;
}
}Em celulares, o botão fica a 16px das bordas. Quando o chat é aberto, ele ocupa a maior parte da tela, e o botão fica oculto até o chat ser fechado:

O botão precisa que o chat com IA esteja ativado. Se chat.enabled estiver definido como false em docs.json, clicar nele não fará nada, então não o inclua.
Se você também usa um widget de suporte, como Crisp ou Intercom, ele provavelmente fica no canto inferior direito. Para separá-los, use left: 24px em vez de right em #ask-ai-fab ou aumente o valor de bottom para posicionar o botão acima do widget.
Execute o código após cada mudança de página
Seu script é executado uma vez, quando um visitante abre o site pela primeira vez. Depois disso, clicar em um link da documentação troca o conteúdo da página sem recarregá-la, então o script não é executado novamente. O botão Ask AI não é afetado porque está anexado a <body>, que permanece no lugar.
Se seu código lê ou altera o conteúdo da página, ele precisa detectar quando a página muda. Este trecho monitora a coluna principal e verifica se a URL mudou. Coloque-o no mesmo script.js, abaixo do código do botão:
(function () {
var lastPath = location.pathname;
var main = document.getElementById('main-content') || document.body;
function onPageChange() {
// Your per-page code goes here
console.log('Now on', location.pathname);
}
new MutationObserver(function () {
if (location.pathname === lastPath) return;
lastPath = location.pathname;
onPageChange();
}).observe(main, { childList: true, subtree: true });
})();onPageChange é executado uma vez para cada página nova, seja quando o visitante clica em um link da barra lateral, usa a pesquisa ou pressiona o botão Voltar.
Seletores a usar
Os nomes de classe do Jamdesk vêm do Tailwind e podem mudar em qualquer versão. Os rótulos dos botões também mudam, pois são traduzidos em sites multilíngues. Use estes seletores:
| Seletor | Corresponde a |
|---|---|
html.dark | A página enquanto o modo escuro está ativado |
body[data-theme="jam"] | O tema ativo, pelo nome (jam, nebula, pulsar, halo, dusk) |
header[data-has-tabs] | O cabeçalho do site |
#main-content | A coluna principal, incluindo a página e seu índice |
#content-scroll-container | A coluna de conteúdo da página |
article .prose | O texto principal da página atual |
[data-chat-panel] | O painel de chat com IA |
[data-theme-toggle] | O seletor de modo claro/escuro/sistema |
body[data-jd-ready="true"] | Definido quando o carregamento da primeira página termina |
Não mova os próprios elementos do Jamdesk para outros contêineres nem os oculte com scripts. O Jamdesk redesenha partes da página à medida que os visitantes navegam, então um elemento movido pode voltar ao lugar anterior ou interromper a navegação. Adicione seus próprios elementos ao lado dos elementos do Jamdesk, como faz o botão Ask AI.
Teste suas alterações
jamdesk dev exibe seu CSS, mas não executa JavaScript personalizado, e o chat com IA só funciona no site publicado. Para testar o script localmente, cole-o no console do navegador na página de pré-visualização. O botão aparecerá, mas não abrirá o chat até que você publique o site.
Confira o resultado em uma tela do tamanho de um celular (375px de largura) e no modo escuro, não apenas no desktop. É nesses casos que as cores do cabeçalho e os botões com posição fixa costumam apresentar problemas.
