Como adaptei meu blog em Ghost para ter h-card e webmentions — duas coisas que o Ghost, por padrão, não tem.
Rascunho. Anotações de bastidor para eu reescrever depois.
O ponto de partida
Eu gosto do Ghost. Ele é leve, open source, escreve bem e sai da frente. Mas o Ghost nasceu como uma plataforma de publicação e newsletter — não como um cidadão da IndieWeb. Ele não publica um h-card da minha identidade, não marca meus posts com h-entry, e não sabe enviar nem receber webmentions. Para a máquina, meu site era só HTML bonito: humanos liam, software não entendia quase nada.
A ideia deste experimento foi simples: manter o Ghost exatamente como está — sem plugin, sem fork, sem servidor extra rodando ao lado — e ainda assim fazer meu site conversar com a web aberta. Tudo o que se vê aqui mora no tema (Handlebars + um pouco de CSS e JavaScript) e em um serviço hospedado gratuito. Nenhuma linha de código de servidor.
E havia uma regra inegociável que eu me impus: não perder 1% da estética. O blog é uma lista enxuta, quase um diretório retrô. Qualquer coisa que eu adicionasse teria que ser invisível, ou então tão discreta quanto o resto.
Identidade primeiro: o h-card invisível
A base de tudo na IndieWeb é provar quem você é. Isso se faz com microformats — um punhado de nomes de classe que você adiciona ao HTML já existente para que software entenda nome, foto, URL, e-mail, perfis. O h-card é o "cartão de visita" semântico.
No meu caso, eu não queria exibir um cartão na tela; queria que só as máquinas o lessem. A solução foi um bloco h-card escondido no topo de todas as páginas, com o atributo hidden. Os leitores não veem nada; os parsers da IndieWeb leem o HTML normalmente, porque eles ignoram o CSS.
Junto dele, espalhei links rel="me" para meus perfis (GitHub, Codeberg, SourceHut, Mastodon, e por aí vai). É o que consolida "esse domínio e essas contas são a mesma pessoa". O detalhe que quase todo mundo esquece: o rel="me" só fecha o laço se o perfil também apontar de volta para o seu domínio. Sem o link de volta, a verificação não acontece.
Posts que máquinas entendem: h-entry
Identidade resolvida, faltavam os textos. O h-entry é o microformato que marca cada post como uma "entrada" — com título (p-name), conteúdo (e-content), data de publicação (dt-published), URL canônica (u-url), autor e categorias.
A beleza disso é que, de novo, é só nome de classe somado a elementos que já estavam lá. O <article> ganhou h-entry, o <h1> ganhou p-name, o corpo ganhou e-content. As tags do post viraram p-category. O autor ficou embutido como um p-author h-card oculto, reaproveitando a mesma foto do meu cartão.
O único ponto técnico que exigiu atenção foi a data. O dt-published precisa de um formato ISO 8601 com fuso horário, e o tema mostrava só dia/mês. A correção foi separar as coisas: o atributo datetime recebe a data completa, legível por máquina, enquanto o texto na tela continua exatamente como antes. O leitor vê "05 jun"; o parser vê 2026-06-05T23:51:21-03:00. Zero mudança visual.
Marquei tanto os posts individuais quanto a listagem da home — porque leitores de feed da IndieWeb consomem os dois.
Recebendo conversas: webmentions sem servidor
Aqui mora a parte mais interessante. Webmention é o jeito da web aberta de fazer o que curtidas e comentários fazem dentro das redes sociais — só que entre sites independentes. Quando alguém responde ou menciona um post meu a partir do próprio site, eu sou notificado, e aquilo pode aparecer como um comentário aqui.
O problema: receber webmention, na teoria, exige um servidor que valide e guarde cada notificação. Eu não queria rodar isso. A saída foi o webmention.io, um serviço hospedado gratuito que faz todo o trabalho pesado. Do meu lado, bastou anunciar o endereço dele com uma única linha invisível no <head>:
<link rel="webmention" href="https://webmention.io/seudominio.com/webmention">
E só. A partir daí, qualquer menção ao meu site é recebida, verificada e arquivada por eles. Detalhe elegante: o login no webmention.io é feito pelo meu próprio domínio, usando exatamente aqueles rel="me" que eu já tinha colocado. As peças se encaixaram.
(Decidi conscientemente não habilitar pingbacks legados — eles atraem spam demais.)
Mostrando do meu jeito
Receber é metade da história; eu queria exibir essas conversas — mas no meu estilo, não num widget genérico de terceiros que brigasse com o visual do blog.
Optei por um JavaScript pequeno e próprio. Ele lê a API pública do webmention.io pela URL do post (sem precisar de chave), separa as reações (curtidas, reposts) das respostas, e monta a marcação à mão. As reações viram uma fileira compacta de avatares; as respostas, uma lista limpa com a mesma data monoespaçada e a mesma linha pontilhada que uso na home. O nome de quem comentou acende na cor da marca quando você passa o mouse.
E o mais importante para a estética: se não há menções, a seção simplesmente não existe. Nada de "0 comentários", nada de caixa vazia. Silêncio, como deve ser num blog minimalista.
Foi aqui que fechei um ciclo curioso: eu tinha desligado os comentários nativos do Ghost porque não queria "discussão" presa a uma plataforma de membros. Os webmentions são a versão aberta disso — a conversa acontece na web inteira e só ecoa aqui.
O que ainda mora fora
Honestidade técnica: uma metade do webmention — enviar — ainda não está dentro do tema, e nem precisa estar. Quando eu linko outro site da IndieWeb, é preciso disparar uma notificação para ele. Isso se resolve com um serviço externo (como o Bridgy ou o webmention.app) que observa meu feed RSS e envia automaticamente. O tema só precisa do bom h-entry — que já está lá — para que essas notificações saiam com a marcação correta.
Ou seja: a parte "passiva" (ser uma identidade, ter posts legíveis, receber e exibir conversas) está toda no tema, invisível ou discreta. A parte "ativa" (sair avisando outros sites) é um serviço que liga no RSS, sem código.
Por que fazer isso
No fim, nada disso muda como o blog se parece. Um visitante distraído não percebe diferença nenhuma. Mas, por baixo, o site deixou de ser uma ilha. Ele agora se apresenta, prova quem é, marca seus textos de um jeito que qualquer ferramenta aberta entende, e está pronto para receber conversas vindas de qualquer canto da web — sem depender do Ghost para isso, sem depender de nenhuma rede social.
O Ghost continua sendo o Ghost. Eu só ensinei ele a falar um segundo idioma — o da web aberta — e fiz isso sem que ele (nem o leitor) percebesse.
— Pablo Murad
Did this resonate?
Related documents
- 001
- 002
- 003
- 004
- 005