Guia completo para converter qualquer pagina de ferramenta do Chipak Tools para o design system padrao
(baseado em /ferramenta/modelo.html). Inclui checklist, estrutura HTML, CSS obrigatorio,
armadilhas conhecidas e diretrizes de conteudo SEO.
/ferramenta/modelo.html e a referencia canonica. A estrutura, classes CSS, IDs e ordem dos elementos devem ser identicos.ChipakComponents.init('Nome'). Rating, favoritos, report e feedback sao injetados por ChipakFeatures.init('slug'). Voce NAO deve escrever esses elementos manualmente — apenas fornecer os containers e IDs corretos para os componentes funcionarem.gerador-cpf.html e gerador-cnpj.html como referencia pratica. Eles seguem 100% deste manual.Cada pagina de ferramenta segue o template definido em /ferramenta/modelo.html (~2400 linhas). O processo de conversao e:
<style> da pagina.O Chipak Tools e um site estatico componentizado. Isso significa que varios elementos sao injetados em tempo de execucao pelo JavaScript, e nao escritos diretamente no HTML. Entender essa divisao e essencial para nao duplicar codigo nem esquecer de fornecer os hooks necessarios.
ChipakComponents.init('Nome') injeta automaticamente| Componente | Onde injeta | O que voce precisa fornecer |
|---|---|---|
| Sidebar completa | #sidebar-container | Um <div id="sidebar-container"></div> vazio |
| Auth modal (login/cadastro) | body (append) | Nada — e 100% automatico |
| Mobile bottom nav | #mobile-nav-container | Um <div id="mobile-nav-container"></div> vazio |
| User menu updates | #loggedOutMenu, #loggedInMenu, #userAvatar, #userName | O HTML do header com esses IDs (veja secao 3) |
| Sidebar logo link | #sidebarLogoLink | Automatico — atualiza href baseado no estado de login |
ChipakFeatures.init('slug') injeta automaticamente| Feature | O que injeta/faz | O que voce precisa fornecer |
|---|---|---|
| Rating (estrelas) | Carrega nota e contagem do Firestore, atualiza UI | #starRating com 5 buttons + #ratingScore + #ratingCount + #ratingThankyou |
| Favoritos | Verifica estado no Firestore, alterna botoes | #btnFavoriteOff + #btnFavoriteOn (dois botoes separados!) |
| Report modal | Injeta HTML do modal no body (com SVGs sem width/height) | CSS para .report-modal-* na pagina (senao SVGs ficam gigantes) |
| Feedback modal | Injeta HTML do modal no body (abre para 1-2 estrelas) | CSS para .feedback-modal-* na pagina |
| Funcoes globais | Registra: rateTool(), hoverStars(), unhoverStars(), toggleFavorite(), openReportModal(), sendFeedback(), closeFeedbackModal() | Os handlers onclick nos elementos HTML |
<header class="app-header"> com menu toggle, titulo e user menu. Segue o modelo exato (copie e troque o titulo).<style> (incluindo estilos para modais injetados).A pagina deve seguir exatamente esta arvore. Cada bloco e explicado abaixo.
<title>Nome da Ferramenta Online Gratis - Para Testes | Chipak Tools</title>
<meta name="description" content="Descricao com 150-160 caracteres. Inclua a palavra-chave principal, o beneficio e 'sem cadastro' ou 'gratuito'.">
<meta name="keywords" content="palavra1, palavra2, variacao1, variacao2, variacao longa">
<link rel="canonical" href="https://chipak.tools/ferramenta/slug-da-ferramenta">
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:title" content="Mesmo titulo ou versao curta">
<meta property="og:description" content="Versao curta da description">
<meta property="og:url" content="https://chipak.tools/ferramenta/slug-da-ferramenta">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "Nome da Ferramenta",
"description": "Descricao curta",
"url": "https://chipak.tools/ferramenta/slug",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "Web",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "BRL"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"bestRating": "5",
"worstRating": "1",
"ratingCount": "XXX"
}
}
</script>
O hero e o cabecalho visual principal. Contem:
<div class="tool-hero">
<div class="tool-hero-inner">
<div class="tool-hero-content">
<!-- Badges -->
<div class="tool-hero-badges">
<span class="badge badge-free">...Gratuito</span>
<span class="badge badge-category">Categoria</span>
<span class="badge badge-popular">...Popular</span> <!-- opcional -->
</div>
<h1>Nome da Ferramenta</h1>
<p class="tool-hero-description">Descricao rica em 1-2 frases.</p>
<!-- Meta info -->
<div class="tool-hero-meta">
<span class="tool-hero-meta-item">...XX.Xk usuarios</span>
<span class="tool-hero-meta-item">...Atualizado em Mes Ano</span>
<span class="tool-hero-meta-item">...X.X/5</span>
</div>
<!-- Star Rating (IDs OBRIGATORIOS) -->
<div class="star-rating">
<span class="star-rating-label">Avalie esta ferramenta:</span>
<div class="star-rating-stars" id="starRating">
<!-- 5 buttons com data-value="1" a "5" -->
<!-- onclick="rateTool(N)" onmouseenter="hoverStars(N)" onmouseleave="unhoverStars()" -->
</div>
<span class="star-rating-score" id="ratingScore">X.X</span>
<span class="star-rating-count" id="ratingCount">(XXX votos)</span>
<span class="star-rating-thankyou" id="ratingThankyou">...Obrigado!</span>
</div>
</div>
<!-- Actions (IDs OBRIGATORIOS para favoritos) -->
<div class="tool-hero-actions">
<button class="btn-favorite" id="btnFavoriteOff" onclick="toggleFavorite()">...Favoritar</button>
<button class="btn-favorite active" id="btnFavoriteOn" onclick="toggleFavorite()" style="display:none;">...Favoritado</button>
<button class="btn-share" onclick="shareTool()">...Compartilhar</button>
<button class="btn-report" onclick="openReportModal()">...Reportar Bug</button>
</div>
</div>
</div>
chipak-features.js procura por #btnFavoriteOff e #btnFavoriteOn separadamente.
Se voce usar um unico botao com toggle de classe, os favoritos NAO funcionam. Sempre use dois botoes, com o btnFavoriteOn comecando com style="display:none;".
<div class="tool-tabs">
<button class="tool-tab active" onclick="switchTab('ferramenta')" data-tab="ferramenta">
...Ferramenta
</button>
<button class="tool-tab" onclick="switchTab('sobre')" data-tab="sobre">
...Sobre
</button>
</div>
<div class="tool-tab-panel active" id="tab-ferramenta">...</div>
<div class="tool-tab-panel" id="tab-sobre">...</div>
A funcao switchTab() deve ser definida no script da pagina:
function switchTab(tabName) {
document.querySelectorAll('.tool-tab').forEach(tab => {
tab.classList.toggle('active', tab.dataset.tab === tabName);
});
document.querySelectorAll('.tool-tab-panel').forEach(panel => {
panel.classList.toggle('active', panel.id === 'tab-' + tabName);
});
}
Contem tres blocos nesta ordem:
div.tool-section — A ferramenta em si (inputs, botao principal .btn-calculate, resultado .result-display, acoes secundarias .actions-row, historico).div.instructions-card — "Como Usar" em 3-4 passos com .step-item numerados.div.info-card — Resumo sobre a ferramenta + usos permitidos + aviso legal.Ver secao 7. Conteudo e SEO para detalhes completos.
<div class="related-tools">
<div class="related-tools-title">...Ferramentas Relacionadas</div>
<div class="related-tools-grid">
<a href="/ferramenta/slug" class="related-tool-card">
<div class="related-tool-icon">...svg...</div>
<div class="related-tool-info">
<div class="related-tool-name">Nome</div>
<div class="related-tool-desc">Descricao curta</div>
</div>
</a>
<!-- 3-4 ferramentas relacionadas -->
</div>
</div>
Escolha 3-4 ferramentas do mesmo grupo tematico. Se a ferramenta e um gerador, inclua o validador correspondente e vice-versa.
<style> da pagina deve conter TODAS as classes CSS listadas abaixo. NAO dependa apenas do styles.css global — ele nao contem as classes especificas do modelo de ferramenta.
As classes CSS se dividem em dois grupos:
| Classe | O que estiliza |
|---|---|
.breadcrumbs | Navegacao de migalhas |
.tool-hero, .tool-hero-* | Cabecalho hero (badges, h1, meta) |
.badge, .badge-free, .badge-category, .badge-popular | Etiquetas do hero |
.star-rating, .star-rating-* | Sistema de avaliacao por estrelas |
.btn-favorite, .btn-share, .btn-report | Botoes de acao do hero |
.tool-tabs, .tool-tab, .tool-tab-panel | Sistema de abas |
.tool-section, .section-title | Container principal da ferramenta |
.input-grid, .input-wrapper, .input-field, .input-label, .input-hint | Campos de formulario |
.checkbox-group, .checkbox-label, .checkbox-sublabel | Opcoes com checkbox |
.btn-calculate | Botao principal de acao (gradiente) |
.actions-row | Linha de botoes secundarios |
.result-display, .result-value, .result-placeholder | Area de resultado |
.history-section, .history-list, .history-item | Historico de resultados |
.alert-box, .alert-box.warning | Caixas de alerta/dica |
.instructions-card, .step-item, .step-number | Card "Como Usar" |
.info-card | Card informativo |
.article-section, .article-header, .article-toc, .article-body | Artigo SEO (aba Sobre) |
.related-tools, .related-tool-card | Ferramentas relacionadas |
chipak-features.js injeta modais (report e feedback) diretamente no DOM com SVGs que NAO possuem width/height.
Se a pagina nao tiver o CSS correspondente, os SVGs renderizam no tamanho total do viewport, causando icones gigantes.
Isso ja aconteceu e e o bug mais recorrente ao converter paginas.
Estas classes DEVEM estar no <style> de TODA pagina de ferramenta:
| Classe | Por que e necessaria |
|---|---|
.report-modal-overlay | Overlay do modal de report (display:none por padrao, flex quando .active) |
.report-modal | Container do modal (max-width: 500px) |
.report-modal-header | Cabecalho com titulo + botao fechar |
.report-modal-header h3 svg | Limita SVG do titulo a 20x20px |
.report-modal-close | Botao X de fechar |
.report-modal-body | Corpo do modal |
.report-type-grid | Grid 2 colunas das opcoes de tipo de report |
.report-type-option | Cada opcao de tipo |
.report-type-option svg | Limita SVG das opcoes a 16x16px — sem isso, ficam GIGANTES |
.report-modal-footer | Rodape com botoes |
.feedback-modal-content | Container do modal de feedback (max-width: 480px) |
.feedback-stars-display | Estrelas dentro do modal |
.feedback-stars-display svg | Limita SVG das estrelas a 24x24px |
.toast-container, .toast | Notificacoes toast (posicao fixa, z-index alto) |
gerador-cpf.html (que ja esta validado) e so adaptar as classes especificas da ferramenta, se houver.
Tres breakpoints obrigatorios:
@media (max-width: 1024px) — Sidebar escondida, main sem margin-left@media (max-width: 768px) — input-grid 1 coluna, hero vertical, botoes full-width, article menor@media (max-width: 640px) — mobile-bottom-nav visivel, padding-bottom extra, hero h1 menorMais as classes base de .mobile-bottom-nav e .mobile-nav-item (usadas pelo componente injetado).
O chipak-features.js e o components.js buscam estes elementos por ID. Se faltarem, a funcionalidade falha silenciosamente.
| ID | Usado por | Descricao |
|---|---|---|
#sidebarOverlay | components.js | Overlay para fechar sidebar no mobile |
#sidebar-container | components.js | Onde a sidebar e injetada |
#userMenu | components.js | Container do menu de usuario |
#loggedOutMenu | components.js | Botoes Entrar/Cadastrar |
#loggedInMenu | components.js | Menu do usuario logado (comeca display:none) |
#userAvatar | components.js | Inicial do usuario |
#userName | components.js | Nome do usuario |
#userDropdown | components.js | Dropdown do usuario |
#mobile-nav-container | components.js | Onde o nav mobile e injetado |
#toastContainer | components.js | Container de toasts |
#starRating | chipak-features.js | Container das estrelas de avaliacao |
#ratingScore | chipak-features.js | Nota media exibida |
#ratingCount | chipak-features.js | Contagem de votos |
#ratingThankyou | chipak-features.js | Mensagem "Obrigado!" apos avaliar |
#btnFavoriteOff | chipak-features.js | Botao favoritar (estado OFF) |
#btnFavoriteOn | chipak-features.js | Botao favoritado (estado ON, comeca escondido) |
#starRating precisam ter o atributo data-value="N" (1 a 5)
e os handlers onclick="rateTool(N)", onmouseenter="hoverStars(N)", onmouseleave="unhoverStars()".
Essas funcoes globais sao criadas pelo chipak-features.js.
A ordem dos scripts e importante. Sempre nesta sequencia:
<!-- 1. Bibliotecas de dominio (se a ferramenta precisar) -->
<script src="../js/documentos-br.js"></script>
<!-- 2. Componentes visuais (sidebar, header, auth modal, mobile nav) -->
<script src="../js/components.js"></script>
<!-- 3. Firebase config (inicializa app + auth + firestore) -->
<script src="../js/firebase-config.js"></script>
<!-- 4. Features (rating, favorites, report, feedback) -->
<script src="../js/chipak-features.js"></script>
<!-- 5. Router SPA -->
<script src="../js/chipak-router.js"></script>
<!-- 6. Script inline da pagina -->
<script>
// PRIMEIRO: inicializar componentes
ChipakComponents.init('Nome da Ferramenta');
ChipakFeatures.init('slug-da-ferramenta');
// DEPOIS: funcoes especificas da pagina
function switchTab(tabName) { ... }
function shareTool() { ... }
// ... funcoes da ferramenta ...
</script>
| Funcao | Descricao |
|---|---|
switchTab(tabName) | Alterna entre abas (ferramenta/sobre) |
shareTool() | Usa navigator.share ou copia URL |
As funcoes rateTool(), hoverStars(), unhoverStars(), toggleFavorite(), openReportModal(), sendFeedback() e closeFeedbackModal() sao registradas globalmente pelo chipak-features.js — NAO precisa redefini-las.
O slug passado para ChipakFeatures.init('slug') e usado como chave no Firestore para ratings, favoritos e reports. Deve corresponder ao nome do arquivo HTML sem extensao:
gerador-cpf.html → ChipakFeatures.init('gerador-cpf')validador-cnpj.html → ChipakFeatures.init('validador-cnpj')conversor-base64.html → ChipakFeatures.init('conversor-base64')O texto deve ser rico, informativo e util para quem busca pelo assunto — nao apenas para quem ja sabe o que a ferramenta faz. Alguem que pesquisa "gerador de CNPJ" no Google pode estar querendo:
O artigo deve responder a TODAS essas intencoes de busca, nao apenas a primeira.
Siga este modelo testado:
<div class="article-section" style="margin-top: 0;">
<div class="article-header">
<div class="article-label">...Artigo</div>
<h2>Titulo longo e descritivo para SEO</h2>
<div class="article-meta">
<span>Por Equipe Chipak</span> • <span>Atualizado em Mes Ano</span> • <span>X min de leitura</span>
</div>
</div>
<div class="article-toc">
<div class="article-toc-title">...Neste artigo</div>
<ol>
<li><a href="#art-oque">Titulo da secao 1</a></li>
<!-- ... -->
</ol>
</div>
<div class="article-body">
<h3 id="art-oque">1. Titulo</h3>
<p>...</p>
<!-- Use <ul>, <ol>, <blockquote>, <strong> para quebrar o texto -->
</div>
</div>
Bugs que ja encontramos ao converter paginas. Leia antes de comecar.
Sintoma: Ao clicar em "Reportar Bug", a pagina mostra icones de onda/formas enormes cobrindo toda a tela.
Causa: O chipak-features.js injeta o modal de report com SVGs que possuem viewBox mas NAO possuem width/height.
Sem CSS para limitar o tamanho, o SVG ocupa o espaco disponivel.
Solucao: Incluir no CSS da pagina as classes .report-type-option svg { width: 16px; height: 16px; }, .report-modal-header h3 svg { width: 20px; height: 20px; } e todas as demais classes de modal listadas na secao 3.2.
Sintoma: Clicar em "Favoritar" nao faz nada, ou o estado nao alterna.
Causa: Usar um unico botao #btnFavorite ao inves de dois botoes separados (#btnFavoriteOff + #btnFavoriteOn).
Solucao: Sempre usar dois botoes. O _initFavorites() do chipak-features.js busca por esses dois IDs especificos e alterna o display entre eles.
Sintoma: Ao dar 1 ou 2 estrelas, nada acontece (o modal de feedback deveria abrir).
Causa: Isso normalmente acontece em paginas que NAO chamam ChipakFeatures.init('slug') (como o dashboard).
Em paginas de ferramenta que chamam init(), o feedback modal e inicializado automaticamente.
Solucao: Certifique-se de que ChipakFeatures.init('slug') e chamado. Se for uma pagina especial sem slug, chame ChipakFeatures._initFeedbackModal() manualmente.
Sintoma: O conteudo fica mais estreito que o esperado.
Causa: Faltou a classe full-width no div.content-area.
Solucao: Usar <div class="content-area full-width">.
Sintoma: Links internos causam reload completo da pagina.
Causa: O chipak-router.js nao foi incluido, ou foi incluido antes do components.js.
Solucao: Incluir chipak-router.js como ultimo script externo, antes do script inline.
Sintoma: Notificacoes de "Copiado!" nao aparecem, ou aparecem sem estilo.
Causa: Faltou o <div class="toast-container" id="toastContainer"></div> no HTML, ou faltou o CSS de .toast-container e .toast.
Solucao: Verificar ambos: o elemento no HTML e o CSS.
Use esta lista para verificar cada pagina antes de considerar a conversao concluida.
Manual criado em Março 2026 — Chipak Tools
Referencia: /ferramenta/modelo.html | Exemplos convertidos: gerador-cpf.html, gerador-cnpj.html