Tutorial

Como eu construi meu blog com Notion

Explicar como usei o Notion para criar o meu blog

revisado em

Tem um tempo que eu queria um lugar pra publicar o que escrevo. Anotações, ideias soltas, coisas que vão aparecendo (uma espécie de digital garden). E também precisava de algo mais estruturado, pra servir de material pros vídeos que vou começar a fazer no YouTube.

Durante muito tempo usei o Obsidian como meu segundo cérebro, e há pouco migrei pro Notion pela facilidade de compartilhar com o meu time de desenvolvimento. Foi aí que veio a pergunta óbvia: por que não montar meu próprio blog usando o Notion como CMS, com o meu visual, do jeito que eu quiser? Se todo mundo precisa construir suas próprias coisas, essa seria mais uma delas.

E foi o que eu fiz. Hoje eu escrevo no Notion como já tô acostumado, e o que marco como pronto aparece no meu site, com o meu endereço, aberto pra qualquer um ler.

Tudo meu, do conteúdo ao design. Documentei caso você queira se inspirar, ou copiar direto o que montei. É o que vem na sequência.

O que você vai fazer

A montagem é basicamente duplicar dois templates que já deixei prontos: um com o código do blog, no GitHub, e outro com a database dos posts, no Notion. Depois é juntar os dois na Vercel, que é onde o site fica hospedado.

Seguindo o passo a passo, dá pra ter tudo isso no ar sem programar nem abrir um terminal, só clicando e copiando o que eu fiz. No fim você vai ter um blog funcionando, idêntico ao meu.

Mas a graça não é você ter o MEU blog. A graça é você ter o seu. Aí é com você e um agente de programação, iterando até o design ficar do seu jeito. Mais pra frente coloquei algumas dicas, mas a construção é tua.

Uma última coisa antes de começar: a configuração vem em duas rodadas. Primeiro você prepara o Notion e separa alguns valores. Depois cria o projeto na Vercel, porque parte das informações só passa a existir quando o site já está no ar.

Antes de começar: as contas

Você vai usar três serviços, e provavelmente já tem conta em algum deles. Se faltar algum, é só criar, todos têm plano gratuito que já é suficiente pra gente.

  • Notion (notion.so), que vai virar o painel dos posts.
  • GitHub (github.com), onde o código do blog vai morar.
  • Vercel (vercel.com), que hospeda o site e coloca no ar.

Preparar o Notion

Duplicar o template do GitHub

Esse é o template com o código do blog. Abre o repositório:

https://github.com/alexandre-axioma/blog-notion-template

Clica em Use this template e cria um repositório novo na sua conta. Pode dar o nome que quiser, tipo meu-blog, tanto faz.

Não precisa baixar nem clonar nada agora. Mais pra frente a Vercel puxa esse repositório direto do GitHub.

Duplicar o template do Notion

Esse é o outro template, o que vira o painel dos seus posts. Você vai abrir ele aqui:

https://fixed-sushi-1bf.notion.site/Blog-Notion-Template-f1d13d4a408c8285a99c01101e736767

Clica em Duplicate e escolhe a workspace onde você quer o blog. Vem tudo junto, a página, a database e alguns posts de exemplo.

Vale entender o que você acabou de copiar, porque são duas coisas com nomes parecidos. A database Blog Content Management é onde os posts realmente vivem, cada post é uma linha, com título, status, data e o resto. Já a página Blog Notion Template é só uma tela montada por cima dessa database, com algumas views pra você visualizar e organizar os posts de um jeito mais agradável. O conteúdo é o mesmo, a página é só uma janela pra ele.

Essa diferença importa porque mais pra frente a Vercel vai pedir o ID da database, e não o da página. São coisas distintas no Notion e têm IDs distintos. Te mostro como pegar o certo na hora.

Entender a database

Não precisa criar nada disso, as propriedades já vêm no template. Essa lista é só pra você saber pra que serve cada campo quando for escrever.

PropriedadePara que serve
TituloO título do post. Se você deixar o Slug vazio, o site gera a URL a partir daqui.
StatusDecide se o post aparece no blog. Use Publicado pra publicar.
Data de PublicaçãoA data do post. Também é o que permite agendar (veja abaixo).
Resumo do ConteúdoO texto curto que aparece na home, nos previews e no SEO.
CategoriaAgrupa os posts por tema.
TagsPalavras-chave ou temas secundários.
SlugA URL do post, tipo meu-primeiro-post.
LinkOpcional, pra guardar uma referência externa.
Quantidade de PalavrasO blog usa pra estimar o tempo de leitura.
HeroA imagem principal do post.
ThumbA imagem dos cards e listagens.
SEO ScoreOpcional, preenchido pelo extra de auditoria de SEO.

As duas que mais importam são Status e Data de Publicação. Pra um post ir pro ar, o Status precisa estar como Publicado (também vale Published ou Publish). E pra agendar, deixa o Status como Programado ou Scheduled e põe uma data futura em Data de Publicação. O post fica guardado e só aparece quando a data chega.

O resto dos campos eu não detalhei de propósito, ficaria longo demais e a maioria é autoexplicativa. No vídeo eu explico com mais calma cada um.

Criar a integration do Notion

Pro site conseguir ler a sua database, o Notion exige que você crie uma integration e dê pra ela uma chave de acesso. É isso que essa etapa faz, e é tudo numa tela só.

Vai na área de integrations do Notion:

https://www.notion.so/profile/integrations

Clica em New integration (ou New connection, dependendo da versão), dá um nome tipo Meu Blog, escolhe a workspace onde você duplicou o template e cria. Isso te leva pra tela da connection, e o resto da configuração acontece toda aqui.

Primeiro, o Access token, na aba Configuration. Copia ele e guarda, é o valor que a Vercel vai pedir depois como NOTION_TOKEN.

Ainda nessa aba, ajusta as capabilities. A ideia é dar pra integration só o acesso que o blog precisa:

  • Read content: ligado, é o que deixa o site ler os posts
  • Update content: depende, veja abaixo
  • Insert content: desligado
  • No user information: selecionado

O Update content é a única decisão aqui, e ela tem a ver com um extra opcional de SEO. Esse extra roda de tempos em tempos, passa nos seus posts publicados e grava em cada um a nota que o Google dá de SEO, ali no próprio Notion. Serve só pra você ter uma noção de como seus posts estão ranqueando, nada além disso. Pra ele conseguir escrever essa nota de volta, a integration precisa do Update content ligado.

Se isso te interessa, liga o Update content agora e já deixa pronto. A configuração do resto (uma chave do Google, basicamente) fica pra mais pra frente, num bloco só sobre isso. Se você só quer escrever e publicar, deixa desligado e esquece, o blog funciona perfeitamente sem.

Por último, falta liberar o acesso. O token diz quem é a integration, mas não dá acesso a nada por padrão, você ainda precisa apontar quais páginas e databases ela pode ler. Vai na aba Content access, clica em Edit access, marca a página Blog Notion Template (e a Blog Content Management, se ela aparecer separada) e salva.

Antes de sair, confere uma coisa: a aba Content access não pode estar vazia. Se ficar, o site não lê os seus posts por mais que o token esteja certo.

Copiar o ID da database

Essa é a hora que eu prometi lá atrás. Você precisa do ID da database Blog Content Management, não o da página.

No menu lateral, abre a Blog Content Management em tela cheia e copia a URL. O ID é a sequência de letras e números do endereço. Se tiver um ?v=, pega só o que vem antes; o que vem depois é o ID da view.

https://www.notion.so/2dfd76f2b52383c690cb01b9164f0ff7?v=48ad76f2b52383d29bf3887c4474f1fd

Nesse caso, o ID é:

2dfd76f2b52383c690cb01b9164f0ff7

É esse valor que vai na variável NOTION_BLOG_DATABASE_ID na Vercel.

Ativar o SEO (opcional)

Esse é o extra que comentei lá em cima, quando você decidiu sobre o Update content. Se deixou desligado, pula pra próxima etapa. Nada aqui é necessário pro blog funcionar.

Se ligou, o que falta agora são duas chaves. Te adianto que a config do SEO se divide em dois momentos por causa do fluxo. Essas chaves entram como variáveis na criação do projeto, então têm que ficar prontas antes da Vercel. Já a parte que faz tudo rodar sozinho depende de o site ter um endereço público, então só dá pra ligar lá na frente, num bloco à parte. Por enquanto, as chaves.

Uma delas é um segredo seu, pra proteger a rota de auditoria de quem não deveria estar chamando ela. Gera uma senha longa, uns 32 caracteres pra cima, no gerador do Bitwarden ou onde você quiser.

https://bitwarden.com/password-generator/

SEO_AUDIT_SECRET=uma_senha_longa_e_aleatoria

A outra é uma chave do Google PageSpeed, e essa é opcional até dentro do opcional. A API roda sem chave, mas o Google recomenda uma quando as consultas são frequentes, que é o que acontece num audit automático. Se quiser, começa sem e adiciona depois.

Pra gerar, abre a API do PageSpeed no Google Cloud e habilita ela:

https://console.cloud.google.com/apis/library/pagespeedonline.googleapis.com

Depois vai em credenciais e cria uma API key:

https://console.cloud.google.com/apis/credentials

  1. Clica em Create credentials e escolhe API key.
  2. Dá um nome qualquer, tipo Blog.
  3. Em API restrictions, seleciona PageSpeed Insights API.
  4. Em Application restrictions, deixa None.
  5. Clica em Create e copia a chave.

Quem usa essa chave é o backend do site, não o navegador, então não tem por que prender ela a um domínio em Application restrictions. O que vale restringir mesmo é a API, no passo 3.

PAGESPEED_API_KEY=sua_chave_do_pagespeed

Publicar na Vercel

Juntar tudo antes da Vercel

Agora é só reunir o que você separou até aqui, porque tudo isso vai ser colado de uma vez na criação do projeto.

Pra qualquer blog, os dois essenciais são:

NomeValor
NOTION_TOKENO access token da integration
NOTION_BLOG_DATABASE_IDO ID da database Blog Content Management

E se você foi pelo caminho do SEO, junta também estes:

NomeValor
SEO_AUDIT_SECRETA senha que você gerou
PAGESPEED_API_KEYA chave do Google (se você criou)

Deixa esses valores à mão. No próximo passo você cria o projeto na Vercel e cola todos eles de uma vez.

Criar o projeto

Entra na Vercel, clica em Add New e depois em Project, e importa o repositório que você criou lá no GitHub.

https://vercel.com

Ela vai identificar que é um projeto Astro, não precisa mexer em nada disso. Antes de dar o deploy, vai ter um espaço pra adicionar as variáveis de ambiente, e é ali que entram os valores que você juntou no passo anterior. Se você não foi pelo SEO, são só os dois primeiros.

Com tudo no lugar, dá o deploy e espera terminar.

Quando terminar, abre a URL que aparecer e dá uma olhada se os posts em Publicado estão lá. Se estiverem, deu certo, tá tudo funcionando.

Escolher a URL do blog

Depois do primeiro deploy, abre o Overview do projeto na Vercel. Em Production Deployment tem um campo Domains, e é ali que está a URL boa do seu blog, algo tipo meu-blog-chi.vercel.app. Essa é a que você vai usar pra tudo daqui pra frente.

A Vercel também mostra uma URL bem mais longa, do deployment específico. Essa não serve, ela muda a cada deploy. Fica sempre com a do Domains, que é estável.

Se você quiser usar um domínio seu, tipo blog.seudominio.com, dá pra configurar agora em Add Custom Domain. É seguir as instruções de DNS que a Vercel mostra e esperar ficar ativo, e aí é esse domínio que você usa no lugar do .vercel.app nos próximos passos.

Guarda essa URL, qualquer que seja a sua. Ela é a base do webhook que a gente vai montar pra publicação automática.

Ligar a publicação automática

Criar o deploy hook da Vercel

O deploy hook é uma URL especial da Vercel. Quem chamar ela dispara um rebuild do site, e é exatamente isso que o Notion vai fazer toda vez que você publicar um post.

Na Vercel, vai em Settings, depois Git, e procura por Deploy Hooks. Cria um com um nome qualquer, tipo notion-blog-publish, aponta pra branch principal (normalmente main) e copia a URL que ela gera.

Essa URL vira mais uma variável de ambiente. Volta em Settings, depois Environment Variables, e adiciona ela como VERCEL_DEPLOY_HOOK_URL.

Criar o webhook do Notion

Agora é avisar o Notion pra chamar aquele deploy hook sempre que algo mudar nos seus posts. Isso é um webhook, e ele aponta pra uma rota que já existe no seu site, a sua URL com /api/notion-webhook no final.

Então se o seu blog está em meu-blog-chi.vercel.app, o endereço do webhook é:

https://meu-blog-chi.vercel.app/api/notion-webhook

Se você pôs domínio próprio, usa ele no lugar, mesma coisa com /api/notion-webhook no fim.

Esse webhook se cria na mesma connection do Notion de antes, na aba Webhooks.

https://www.notion.so/profile/integrations

Cria uma nova subscription, cola a URL do seu site e, em API version, deixa a mais recente que aparecer. Aí vem a parte que exige atenção, os eventos. O Notion deixa marcar um monte deles, mas o template só usa três. Expande o grupo Page e marca só estes:

EventoDispara quando
page.createdvocê cria um post novo na database
page.properties_updatedvocê muda uma propriedade, tipo Status, Slug ou Data de Publicação
page.deletedum post vai pra lixeira

Todo o resto fica desmarcado, inclusive o page.content_updated. Esse último é de propósito: ele dispararia a cada vez que o Notion salva o corpo do texto sozinho, e você acabaria com um rebuild a cada palavra digitada. O blog publica com base nas propriedades, não no autosave.

Vai parecer que o grupo Page ficou só parcialmente marcado, uns 3/8 events. É assim mesmo. Clica em Create subscription.

Verificar o webhook

Assim que você cria a subscription, o Notion avisa que o endpoint ainda precisa ser verificado. Isso é esperado. Por baixo, o Notion mandou um token pra sua rota no momento da criação, e o código do template já pega esse token e joga ele nos logs da Vercel pra você.

Então vai nos logs da função na Vercel e procura uma linha assim:

Notion webhook verification token: ...

Copia o que vem depois dos dois pontos. Esse é o token, e ele vira a última variável de ambiente do projeto. Adiciona ele na Vercel como NOTION_WEBHOOK_VERIFICATION_TOKEN e agora sim faz o redeploy, que de quebra também ativa o VERCEL_DEPLOY_HOOK_URL que você tinha salvado antes.

Com o site no ar de novo, volta na aba Webhooks do Notion, clica em Verify, cola o mesmo token e confirma.

https://www.notion.so/profile/integrations

Pronto, o webhook fica ativo e o Notion já consegue avisar o site quando você mexer nos posts.

Testar a publicação automática

Agora o teste que vale por tudo. Vai no Notion e cria um post novo na database, preenche os campos como faria de verdade, Titulo, Resumo do Conteúdo, Categoria, Slug, Data de Publicação, e escreve algumas linhas no corpo do post também, qualquer coisa, só pra ele não nascer vazio. Aí põe o Status como Publicado.

Volta na Vercel e fica de olho. Em alguns segundos um deployment novo começa sozinho, sem você ter feito nada. Esse é o webhook funcionando. O Notion avisou a Vercel, e ela está reconstruindo o site. Quando terminar, abre a home do blog e o post novo tem que estar lá.

Se apareceu, acabou. O ciclo inteiro está de pé, você escreve no Notion, marca como publicado, e o blog se atualiza sozinho. É isso que você montou.

Depois que estiver no ar

Como atualizar um post

Tem um detalhe no uso do dia a dia que vale saber. Como o blog ignora mudanças no corpo do texto (pra não ficar republicando a cada autosave), editar só um parágrafo do post nem sempre dispara um novo deploy. O texto muda no Notion, mas o site não percebe.

Pra forçar a republicação, é só mexer numa propriedade depois de editar, porque é isso que o webhook escuta. O truque mais fácil é mudar o Status pra qualquer outra coisa e voltar pra Publicado. Isso conta como uma mudança de propriedade e o site reconstrói com o texto novo.

Rodar o SEO audit

Se você foi pelo caminho do SEO lá atrás, é aqui que ele entra em operação. Quem deixou desligado pode pular essa parte inteira.

A boa notícia é que metade do trabalho já está feito. Aquelas duas chaves que você gerou (o SEO_AUDIT_SECRET e o PAGESPEED_API_KEY) já estão na Vercel desde a criação do projeto, e o GitHub Action que faz tudo rodar sozinho já vem junto no template, em .github/workflows/seo-audit.yml. Você não precisa criar nem colar nada.

O que falta é só dar pro GitHub as duas informações que ele precisa pra chamar a rota do audit no seu site. Isso vai como repository secret. No repositório do seu blog no GitHub, vai em Settings, depois Secrets and variables, depois Actions, e cria dois novos secrets:

NomeValor
SEO_AUDIT_SECRETO mesmo valor que você colocou na Vercel
SEO_AUDIT_URLA URL do seu blog com /api/seo-audit no final

Com os dois salvos, o Action já passa a rodar sozinho perto de quatro vezes por hora, passando nos seus posts publicados e gravando a nota de SEO no Notion. Se quiser ver acontecendo agora, vai na aba Actions do repositório, abre o workflow SEO audit e clica em Run workflow. Em alguns segundos a propriedade SEO Score no Notion deve começar a aparecer preenchida.

Vale dizer que isso aqui é independente da publicação. Quando você publica um post, é o webhook do Notion que faz a Vercel reconstruir o site, e isso já tinha sido configurado lá atrás. O Action de SEO só entra depois, lendo o post que já está no ar pra medir e anotar a nota. Os dois sistemas não se misturam.

Um detalhe da aba Actions: o GitHub às vezes atrasa ou pula execuções agendadas em horários de muita carga, então os horários podem sair irregulares. Isso é normal e não tem o que fazer, faz parte do plano grátis. Pra blogs pequenos não chega a ser um problema, o score continua aparecendo perto da publicação.

Customizar a UI

Daqui pra frente é design, e isso eu não vou conseguir fazer por você. É escolha sua, e a melhor forma de chegar onde você quer é trabalhar com um agente de programação em cima do código, descrevendo o que quer, vendo o resultado e refinando. Eu uso o Claude Code com o Opus 4.7, que hoje é o melhor pra frontend, mas Codex ou outro também resolvem.

Uma coisa que faz bastante diferença é mandar referência visual em vez de tentar descrever o estilo com palavra. Dizer "deixa mais limpo" não leva a lugar nenhum, enquanto um screenshot de um blog que você acha bonito passa em segundos uma informação que você levaria parágrafos pra explicar mal. E isso funciona ainda melhor agora porque o Opus 4.7 lê imagem numa resolução bem mais alta que os modelos anteriores, então um print de uma página inteira que antes chegava borrado e fazia ele perder detalhe agora é lido com nitidez de tipografia, espaçamento e cor. Vale juntar quantas referências você tiver.

Outra coisa é resolver o design aos poucos em vez de pedir pra ele refazer tudo de uma vez, que costuma dar errado. Começando pela home, depois a página de post, e assim por diante, fica mais fácil acompanhar o que mudou e voltar atrás quando alguma coisa sai errado.

Vale dar uma olhada na skill frontend-design, da Anthropic, que carrega no agente um monte de boa prática de design e ajuda principalmente quando você sente que algo está errado mas não sabe dizer o quê.

https://www.skills.sh/anthropics/skills/frontend-design

Tô preparando um conteúdo só sobre fazer um bom UI/UX com agente, com bem mais profundidade que essas dicas soltas. Quando sair, atualizo esse post com o link, então se chegou até aqui, fica de olho.

É isso

No fim das contas, o que você montou é simples de dizer. Um lugar seu na internet, alimentado pelo Notion, que se você ainda não usa, deveria. Você escreve lá dentro, marca o post como pronto, e o resto acontece sozinho.

A parte técnica acaba aqui, mas o blog em si tá só começando. Ele ainda tem a minha cara, não a sua. O que vai fazer ele virar seu de verdade é o que você vai fazer a partir de agora, escrevendo nele e deixando ele com o seu jeito.

Se montar o seu, queria muito ver.