Ir para o conteúdo principal

Destaque

Portfólio pessoal e cases

Desenvolvedor Frontend Sênior · 2026 · 4 min de leitura

Portfólio Astro estático: cases bilíngues tipados, UI editorial paper-first, quase zero JS por padrão, mais superfícies agent-readable (llms.txt, JSON Resume, MCP). O www em produção mantém analytics adiados e Bot Fight da Cloudflare.

Caminho rejeitado: Usar Next.js App Router em todas as páginas

Visão geral

Precisava de um lugar para mostrar como trabalho, não uma galeria de miniaturas. Este site é Astro estático com cases em MDX (EN como fonte, overlays pt-BR), rail tipográfico de trabalhos selecionados na home, prateleira de produtos, folios anuais de Comunidade, Playwright nos fluxos críticos e endpoints máquina para agentes e ferramentas consultarem os mesmos fatos sem scrapar HTML.

Problema

A maioria dos portfólios parece intercambiável: tema escuro, cargo no hero, grades de cards e pouca prova de julgamento. Também deixam crawlers de IA e tooling de agentes adivinharem a partir de HTML bagunçado.

Restrições

  • Zero JavaScript por padrão em páginas de conteúdo; React só se uma interação justificar.
  • Lighthouse Accessibility e SEO fortes na home ao vivo; documentar trocas de Perf com honestidade.
  • Coleções de conteúdo tipadas para cases, palestras e apps.
  • Interface clara com tipografia de jornal e contraste legível; o tema escuro permanece opcional.
  • Medir tráfego real (gtag adiado + Vercel Analytics); não apagar analytics para perseguir nota de fachada.
  • Manter proteções de edge da Cloudflare utilizáveis; não bloquear o challenge no CSP só para subir Best Practices.
  • Um perfil canônico para humanos e agentes (PDF + JSON Resume + MCP).
  • Ferramentas de IA permitidas para velocidade, não para arquitetura sem supervisão.

Arquitetura

Astro para o shell e a lista de trabalhos selecionados na homepage. MDX + overlays i18n para cases e produtos. Tokens CSS vanilla (IBM Plex) para um sistema editorial discreto. Folios por ano e grades de duas colunas em vez de dashboards de cards. Playwright contra o site buildado. Camada de agentes: profile.ts alimenta llms.txt, resume.json, Person JSON-LD e um servidor MCP (stdio + Streamable HTTP na Vercel). Em produção, analytics sobe após idle e o CSP permanece compatível com scripts de challenge da Cloudflare.

Decisões principais

Astro em vez de Next.js

Motivo

Site de conteúdo não precisa de runtime React em toda página.

Alternativas consideradas
  • Usar Next.js App Router em todas as páginas (rejeitado: custo de JS sem benefício)

Lista tipográfica estática de trabalhos selecionados em vez de carrossel hero React

Motivo

O carrossel precisava de ilha para fade e paginação. Uma lista tipográfica prova o mesmo trabalho com zero client JS na homepage.

Alternativas consideradas
  • Manter HeroCarousel como ilha React (rejeitado: interatividade sem valor suficiente)

Analytics adiados em vez de nenhum analytics

Motivo

Portfólio que afirma julgamento técnico ainda deve medir visitas. Analytics sobe após idle com IP anonimizado. Aceitar custo modesto no Lighthouse em vez de site mudo.

Alternativas consideradas
  • Omitir todo analytics por Performance 100 limpo (rejeitado: produto imensurável, nota de fachada)
  • Analytics síncrono no <head> (rejeitado: bloqueia LCP/TBT sem necessidade)

CSP compatível com Cloudflare em vez de scripts travados por hash

Motivo

script-src só com hash bloqueou bootstrap de challenge Cloudflare e forçou desligar Bot Fight por paridade de score. O CSP de produção permite o caminho de challenge para a proteção de edge permanecer ligada.

Alternativas consideradas
  • CSP com hash que bloqueia challenge CF para forçar Best Practices 100 (rejeitado: recurso de segurança desligado por nota de fachada)

Tema claro com tipografia de jornal como padrão, em vez de dark-first

Motivo

Portfólios tech escuros estão saturados. Papel claro com tipografia de contraste mais forte lê melhor na primeira passagem.

Alternativas consideradas
  • Manter dark como padrão (rejeitado: parece todo portfólio de tech)

Uma prateleira Produtos para toda ferramenta entregue

Motivo

StackBrief e Dieta e Treino são produtos disponíveis que as pessoas podem abrir. Separar em Lab fazia o segundo parecer inacabado.

Alternativas consideradas
  • Separar Produtos e Lab (rejeitado: diluiu Dieta e Treino)

Perfil agent-readable (llms.txt + resume.json + MCP) a partir de uma fonte

Motivo

Recrutadores e agentes de IDE já buscam llms.txt e MCP. Um profile.ts alinha Person schema, JSON Resume e tools sem duplicar o corpo dos MDX.

Alternativas consideradas
  • Só HTML e esperar scrapers acertarem (rejeitado)
  • JSON Resume paralelo à mão (rejeitado: drift)

Playwright em vez de testes unitários de componente

Motivo

Testes de browser pegam os fluxos que importam num build estático.

CSS vanilla em vez de Tailwind

Motivo

Estilos escopados e variáveis bastaram aqui.

Stack

  • Astro 5
  • TypeScript
  • MDX + Zod collections
  • Vanilla CSS (IBM Plex)
  • Playwright (E2E)
  • Vercel + Cloudflare
  • Google Analytics (deferred gtag)
  • Vercel Web Analytics
  • MCP (Streamable HTTP + stdio)

Impacto

Lighthouse (www desktop) 99 Perf · 98 A11y · 100 BP · 100 SEO
Lighthouse (www mobile) 89 Perf · 98 A11y · 100 BP · 100 SEO
JS no cliente na homepage Sem ilha React (lista estática)
E2E Playwright 8/8 aprovados
Superfícies para agentes llms.txt · resume.json · /api/mcp

Auditado em 9 ago 2026 com Lighthouse 12.8.2 em https://www.erbsu.com/en/ (Cloudflare + analytics adiados). Desktop fica quase perfeito; Perf mobile é o principal custo do www. Suite Playwright a11y/nav: 8/8. Endpoints agent-readable saem da mesma fonte do PDF.

Aprendizados

  • Tratar JavaScript como custo significa remover ilhas quando uma lista estática basta, não apagar analytics ou segurança de edge para imprimir um placar perfeito.
  • Um 100 conquistado tirando medição e Bot Fight soa como nota de fachada; documente a troca.
  • A primeira impressão falha em copy defensiva e enfeite de template antes de falhar em escolha de stack.
  • Acessibilidade e contraste desde o início superam passada de polimento tardio.
  • Arquivos agent-readable não substituem descoberta orgânica. Tornam citações precisas quando alguém (ou um agente) já chega no domínio.