Este post documenta, passo a passo, como configurei o blog BORTO.LOG até o momento. Serve como referência para mim e para quem quiser reproduzir a mesma stack: Hugo + tema PaperMod, versionado no GitHub, publicado via Cloudflare Pages.
Sumário rápido
- Propósito e decisão da stack
- Pré-requisitos
- Estrutura do repositório e convenções
- Comandos para desenvolvimento local
- Configuração do build e deploy no Cloudflare Pages
- Sistema de comentários com Giscus
- Notas e decisões
Propósito
Criei este blog como um caderno técnico pessoal: anotações, tutoriais, experimentos e documentação do meu dia a dia como engenheiro/desenvolvedor. Precisei de algo rápido para gerar HTML estático, com suporte a temas modernos, boa performance e sem dependências pesadas, por isso escolhi Hugo =)… e por outras razões pessoais.
Por que Hugo + PaperMod + Cloudflare Pages
- Hugo: binário único, build muito rápido, sistema de Page Bundles e suporte a processamento de imagens. Quando usar SCSS/asset pipeline, prefira a versão Extended (Cloudflare Pages já usa versão Extended).
- PaperMod: tema minimalista, suporte a dark/light, busca client-side com Fuse.js, muitas convenções prontas para blogs técnicos.
- Cloudflare Pages: CDN global, deploy por push no GitHub, preview por PR e plano gratuito com SSL automático.
Pré-requisitos
- Git (com suporte a submódulos)
- Conta no GitHub com repositório público (ou privado com Pages/Cloudflare configurado)
- Conta no Cloudflare
- Hugo (recomendo a versão mais recente ou especificar
HUGO_VERSIONno Pages) - Opcional: Hugo Extended (se usar SCSS ou processamento avançado de imagens)
Estrutura do repositório e convenções
.
├── archetypes/
├── content/
│ └── posts/
├── layouts/
├── static/
├── themes/
│ └── PaperMod/ # submódulo git
├── hugo.toml
└── .gitignore
Principais configurações no hugo.toml
baseURL = "https://bortoloso.me/"theme = "PaperMod"defaultContentLanguage = "pt"outputs.home = ["HTML","RSS","JSON"](JSON necessário para busca via Fuse.js)pygmentsUseClasses = trueemarkup.highlight.noClasses = falsepara usar Chroma[params].env = "production"para ativar metatags sociais do PaperMod
Submódulo do tema
O tema PaperMod está como submódulo Git (themes/PaperMod), mantido por .gitmodules. No ambiente de build precisamos inicializá-lo.
Comandos para desenvolvimento local
Iniciar servidor de dev
hugo server -D
# Acesse: http://localhost:1313
Criar um novo post
./new-post.sh nome-do-post
# ou
hugo new posts/nome-do-post/index.md
Atualizar submódulos localmente
git submodule update --init --recursive
Build de produção
hugo --gc --minify
Testar o public/ localmente
cd public
python3 -m http.server 8000
# Acesse: http://localhost:8000
Configuração do build e deploy no Cloudflare Pages
No painel do Cloudflare Pages, ao criar o projeto conectado ao GitHub, use estas opções:
- Branch:
main
Build command
git submodule update --init --recursive && hugo --gc --minify
Output directory
public
Variáveis de ambiente úteis (opcionais)
HUGO_VERSION- definir a versão do Hugo para tornar o build reprodutível- Se usar Extended: defina
HUGO_VERSIONpara uma versão Extended disponível na imagem
Por que esse comando?
git submodule update --init --recursivegarante que o tema PaperMod (submódulo) esteja disponível durante o build.hugo --gc --minifygera o site otimizado e pronto para entrega.
Domínio customizado e SSL
No Cloudflare Pages, adicione o domínio bortoloso.me (você usa o seu, esse é meu hehe) como custom domain no projeto Pages. O Cloudflare gerencia o SSL automaticamente. Se necessário, aponte os registros DNS conforme instruções do Pages (geralmente CNAME/ALIAS apontando para o domínio do Pages).
Observações sobre site.webmanifest e favicons
Coloque todos os ícones gerados (p.ex. pelo RealFaviconGenerator) dentro de static/ e referencie-os em layouts/partials/extend_head.html. Verifique que os arquivos referenciados em static/site.webmanifest existam em static/.
.gitignore e arquivos a não versionar
Recomendo ignorar a saída de build e caches:
/public/
/resources/
hugo_stats.json
node_modules/
.cache/
.env*
Importante: não ignore themes/PaperMod se você converter o submódulo em diretório, mas mantenha-o como submódulo se quiser acompanhar upstream do PaperMod.
Fluxo de publicação
- Criar/editar post localmente (usar
hugo server -Dpara validar). - Confirmar
draft: falseno front matter quando pronto. - Commit e push para
main:
git add .
git commit -m "post: setup inicial"
git push origin main
- O Cloudflare Pages detecta o push, executa o build e publica o site automaticamente.
Sistema de comentários com Giscus
Para adicionar comentários ao blog, configurei o Giscus utilizando GitHub Discussions como backend. Isso oferece uma solução leve e moderna sem necessidade de banco de dados ou serviços pesados.
Pré-requisitos
- Repositório público no GitHub com Discussions habilitada
- Instalar o GitHub App do Giscus: https://github.com/apps/giscus
- Criar uma categoria de discussions (exemplo: “Blog Comments”)
Configuração no hugo.toml
Adicione a configuração do Giscus aos parâmetros:
[params]
comments = true
[params.giscus]
repo = "seu-usuario/seu-repo"
repoId = "R_kgDOSet8pA"
category = "Blog Comments"
categoryId = "DIC_kwDOSet8pM4C9LyN"
mapping = "pathname"
strict = "0"
reactionsEnabled = "1"
emitMetadata = "0"
inputPosition = "bottom"
theme = "light"
lang = "pt"
loading = "lazy"
Os IDs podem ser gerados no configurador oficial: https://giscus.app/pt e depois usados no formato TOML.
Sincronização com o tema PaperMod
Um ponto importante é sincronizar o tema do Giscus com o dark/light mode do PaperMod. O arquivo layouts/partials/comments.html implementa essa sincronização dinamicamente:
- Lê o tema armazenado no
localStorage - Monitora mudanças no toggle do PaperMod
- Atualiza o Giscus via
postMessagequando o tema muda - Funciona corretamente com
data-loading="lazy"
O partial renderiza o Giscus apenas se comments = true e a página não tenha disableComments: true no front matter.
A configuração padrão do Giscus não acompanhava a troca de tema do PaperMod; o partial acima resolve esse problema.
Resultado
Com essa configuração:
- Comentários ficam versionados e armazenados no GitHub
- Login é feito via conta GitHub
- Suporte completo a Markdown
- Reações (reactions) habilitadas
- Tema sempre sincronizado com o blog
- Moderação direta no GitHub Discussions
Notas e decisões importantes
- Usei
archetypes/posts/index.mde o scriptnew-post.shpara acelerar criação de posts. - Preferi não usar GitHub Pages: Cloudflare Pages oferece CDN global com preview e builds rápidos.
- Mantive
env = "production"nohugo.tomlpara ter metadados sociais corretos. - Optei por
pygmentsUseClasses = truepara usar Chroma via classes, evitando JS extra para highlight. - Implementei Giscus com sincronização dinâmica de tema: o sistema de comentários acompanha o dark/light mode do blog em tempo real. (Sobre o Giscus, escrevo outro post em breve.)
