6 min de leitura
Como eu montei esse blog
Por que subdomínio, por que Next.js com MDX, as três tentativas de visual e como funciona a cordinha que apaga a luz do site.
- #blog
- #nextjs
- #css
No primeiro post eu falei que o próximo provavelmente seria sobre como eu montei esse blog. Olha só, cumpri uma promessa kkkk
Já aviso que esse é mais técnico. Se você veio pela parte da vida, pode pular direto pra parte dos visuais, que é mais fofoca do que código.
Subdomínio ou /blog?
A primeira decisão foi onde o blog ia morar. Meu portfólio já fica em gabrieldenardi.com.br, então eu tinha dois caminhos: colocar o blog dentro dele, em /blog, ou criar um projeto separado em blog.gabrieldenardi.com.br.
Muita gente defende o /blog por causa de SEO, porque o Google enxerga tudo como um site só e o blog aproveita a reputação do domínio principal. Mesmo sabendo disso, fui de subdomínio.
O motivo foi bem prático. O portfólio carrega um monte de dependência que um blog não precisa, e juntar os dois ia deixar o build mais pesado à toa. Separado, cada um tem o seu repositório e o seu projeto na Vercel, e eu posso mexer em um sem medo de quebrar o outro.
A stack
Nada de CMS. Cada post é um arquivo .mdx dentro do repositório. Pra publicar, eu crio o arquivo, dou commit e push, e a Vercel faz o resto sozinha.
- Next.js 16, com tudo gerado no build. Quando você abre um post, não tem servidor processando nada, é só um HTML pronto.
- MDX, que é Markdown que aceita componente React. Aquela caixinha de "aviso" do primeiro post é um componente.
- Tailwind 4 pro CSS.
- Shiki pra colorir os blocos de código, com um tema preto e branco que eu fiz pra combinar com o resto.
- Zod validando o cabeçalho de cada post. Se eu esquecer o título ou escrever a data errada, o build quebra e me diz em qual arquivo foi.
O cabeçalho também aceita um draft: true. Post marcado assim só aparece quando eu rodo o projeto na minha máquina. Esse aqui mesmo nasceu como rascunho.
Três visuais até acertar
No primeiro post eu contei isso por cima, então aqui vai a versão completa.
- A cópia do portfólio. Fundo off-white, título em fonte serifada, tudo bem sóbrio. Ficou bonito, mas parecia o portfólio com outro nome, e eu queria que o blog tivesse cara própria.
- A azul. Azul cobalto, a fonte Hubot Sans (da mesma família que o GitHub usa) e um gráfico de commits de enfeite. Parecia uma ótima ideia até eu perceber que era mais enfeite do que blog.
- A preto e branco. Mais descontraída e cheia de animação. Foi a primeira que eu olhei e pensei "beleza, é isso".
As fontes são duas. Nos títulos uso a Anybody, que tem um eixo de largura: dá pra esticar ou espremer as letras sem trocar de fonte, e os títulos daqui usam ela um pouco mais larga que o normal. No texto uso a Atkinson Hyperlegible, que foi desenhada pelo Braille Institute pensando em quem tem baixa visão. Uma letra em que não dá pra confundir l, I e 1 é boa pra todo mundo, ainda mais num blog que tem código.
Os detalhes que eu mais gosto
A cordinha
Lá no canto de cima tem uma cordinha. Puxa e o site troca entre o tema claro e o escuro. Ela balança quando você passa o mouse, estica quando você puxa, e o tema novo se espalha num círculo que sai da ponta dela, como uma luz acendendo.
Esse círculo vem da View Transition API. O navegador tira uma foto da página antes da troca, aplica o tema novo e anima a passagem de um pro outro. Eu só precisei dizer de onde o círculo sai:
::view-transition-new(root) {
animation: lights-out 0.75s cubic-bezier(0.7, 0, 0.25, 1);
}
@keyframes lights-out {
from {
clip-path: circle(0 at var(--switch-x, 100%) var(--switch-y, 0));
}
to {
clip-path: circle(150vmax at var(--switch-x, 100%) var(--switch-y, 0));
}
}O --switch-x e o --switch-y são a posição da pontinha da cordinha, que eu pego com JavaScript na hora do clique. Se o seu sistema estiver configurado pra reduzir animações, o tema troca na hora, sem círculo nenhum. E a escolha fica salva: se você apagar a luz hoje e voltar amanhã, ela continua apagada.
As letras que pulam
O título de cada post é quebrado letra por letra. Cada letra é um span com o seu próprio atraso, e é por isso que elas sobem uma depois da outra quando a página abre. Passa o mouse em cima de uma e ela dá um pulinho torto. Não serve pra absolutamente nada, e é o meu detalhe favorito kkkk
Pra quem usa leitor de tela isso seria um desastre (imagina ouvir o título soletrado), então as letras animadas ficam escondidas dele, e o título inteiro vai junto numa versão invisível.
O rabisco no "vida"
Na página inicial, a palavra "vida" ganha um círculo feito à mão. É um SVG com um truque antigo: o traço começa escondido com stroke-dashoffset e vai aparecendo aos poucos, como se alguém estivesse rabiscando na hora.
A barra de leitura sem JavaScript
Quando você rola um post, aparece uma barrinha no topo mostrando quanto já leu. Ela é só CSS:
.reading-progress {
animation: progress linear both;
animation-timeline: scroll(root block);
}
@keyframes progress {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}O animation-timeline: scroll() amarra a animação à rolagem em vez do tempo. Rolou metade da página, a animação tá na metade. Sem nenhum listener de scroll. Nos navegadores que ainda não suportam isso, a barra simplesmente não aparece e a vida segue.
O mesmo truque, trocando scroll() por view(), faz as coisas aparecerem conforme você rola a página.
Fora isso tem a faixa inclinada rodando na página inicial (passa o mouse que ela para), os botões com sombra dura que afundam quando você clica e a imagem de compartilhamento de cada post, que é gerada sozinha no build com o título dele.
O que deu errado
Óbvio que não saiu tudo de primeira.
- O título da página inicial nasceu enorme. Diminuí, e aproveitei pra trocar a frase, porque a primeira só falava de código e o blog não vai ser só isso.
- No celular, o rabisco em volta do "vida" invadia a palavra seguinte. Troquei as medidas de pixel pra
em, que acompanham o tamanho da fonte, e engrossei o traço, porque na tela pequena ele quase sumia. - O cabeçalho passava da largura da tela do celular por 8 pixels. Oito. Uma rolagem lateral inteira por causa de oito pixels kkkk
- Tinha botão de RSS no topo e no rodapé, e eu tirei os dois porque só ocupavam espaço. O feed continua em
/rss.xmlpra quem ainda usa leitor de RSS (respeito muito).
Enfim
O blog tá pronto, e agora o difícil passa a ser escrever.
Ah, e depois que ele foi pro ar, meu portfólio resolveu aparecer inteirinho em Times New Roman. O código tava certo e o problema era outro, mas isso rende um post só dele.
Se quiser saber como alguma dessas coisas funciona por dentro, me manda um e-mail pelo botão aqui embaixo.