This site had two pages of content. Serving them took a static site generator, a
theme vendored as a git submodule pinned to a commit from 2019, an SCSS build cache checked
into the repository, and a deploy that pushed the result over FTP using a third-party action
pinned to a mutable @master ref.
Este site tinha duas páginas de conteúdo. Para servir isso eram necessários um
gerador de site estático, um tema vendorizado como submódulo git travado num commit de 2019,
um cache de build SCSS commitado no repositório e um deploy que empurrava o resultado por FTP
usando uma action de terceiro travada numa ref mutável @master.
None of that was a problem, exactly. It worked. It had worked for years. But I kept opening the repo, remembering how it was wired, and closing it again — which is a slow way of saying I had stopped writing anything.
Nada disso era exatamente um problema. Funcionava. Funcionou por anos. Mas eu abria o repositório, lembrava como aquilo era ligado, e fechava de novo — que é um jeito lento de dizer que eu tinha parado de escrever.
What the overhead actually was
Qual era o overhead de verdade
Three things, and only one of them is about convenience:
Três coisas, e só uma delas é sobre conveniência:
- A supply chain I did not control. A deploy action on
@masterholds my FTP credentials and can change under me between one push and the next. - A theme frozen in 2019. Every visual change meant reading somebody else's SCSS to find the variable that would let me override it.
- A build step between me and the output. To answer "why is this margin here" I had to run the generator, not read a file.
- Uma cadeia de suprimentos que eu não controlava. Uma action de deploy em
@mastersegura minhas credenciais de FTP e pode mudar sozinha entre um push e o seguinte. - Um tema congelado em 2019. Qualquer mudança visual significava ler o SCSS dos outros pra achar a variável que me deixaria sobrescrever aquilo.
- Um build entre mim e o resultado. Pra responder "por que essa margem está aqui" eu tinha que rodar o gerador, não ler um arquivo.
What replaced it
O que entrou no lugar
Four HTML files, one stylesheet, one script, and a GitHub Pages artifact deploy that
publishes the site/ subdirectory so repository sources never reach the published
tree:
Quatro arquivos HTML, uma folha de estilo, um script e um deploy de artefato do
GitHub Pages que publica o subdiretório site/, de forma que os fontes do
repositório nunca chegam à árvore publicada:
site/ everything that gets published
index.html
about/
projects/
blog/
404.html
css/style.css
js/main.js language toggle and tag filter
assets/ source files, NOT published
Preview is python3 -m http.server 8000 --directory site. The URL
structure is identical to production because there is no transformation between them — what
is in the folder is what is on the domain.
O preview é python3 -m http.server 8000 --directory site. A estrutura
de URL é idêntica à de produção porque não existe transformação entre as duas — o que está na
pasta é o que está no domínio.
Bilingual without a pipeline
Bilíngue sem pipeline
Both languages ship in the same markup. Every translatable string exists twice,
tagged with lang, and CSS hides the inactive one:
Os dois idiomas vão no mesmo markup. Cada string traduzível existe duas vezes,
marcada com lang, e o CSS esconde a inativa:
html[data-lang="en"] [lang="pt-BR"],
html[data-lang="pt-BR"] [lang="en"] { display: none !important; }
A short script flips data-lang on <html> and stores
the choice. It is loaded synchronously in <head>, so the right language is
set before the body paints — no flash of the wrong one. With JavaScript disabled the page keeps
the language hardcoded in the file and still renders correctly. The cost is real: every
paragraph is written twice, and this post is no exception.
Um script curto troca o data-lang no <html> e
guarda a escolha. Ele é carregado de forma síncrona no <head>, então o idioma
certo é definido antes do body pintar — sem flash do idioma errado. Com JavaScript desligado a
página mantém o idioma fixo no arquivo e renderiza normalmente. O custo é real: cada parágrafo
é escrito duas vezes, e este post não é exceção.
Zero external requests
Zero requisições externas
System monospace stack, inline SVG icons, no CDN, no analytics, no font service. The page loads from one origin and asks nobody else for permission to finish rendering. This is the part I would keep even if I went back to a generator.
Stack de monoespaçada do sistema, ícones SVG inline, sem CDN, sem analytics, sem serviço de fontes. A página carrega de uma origem só e não pede permissão pra mais ninguém pra terminar de renderizar. Essa é a parte que eu manteria mesmo se voltasse pra um gerador.
What I gave up
O que eu abri mão
Honestly: this does not scale, and I know exactly where the wall is. Every new post is a new folder with a full HTML document in it, and the index, the sitemap and the RSS feed are updated by hand. At twenty or thirty posts that becomes the kind of repetitive work I write tools to avoid — and when it does, I will write the tool, and it will be mine.
Sinceramente: isso não escala, e eu sei exatamente onde está a parede. Cada post novo é uma pasta nova com um documento HTML inteiro dentro, e o índice, o sitemap e o feed RSS são atualizados na mão. Em vinte ou trinta posts isso vira o tipo de trabalho repetitivo que eu escrevo ferramentas pra evitar — e quando virar, eu escrevo a ferramenta, e ela vai ser minha.
Until then, the whole site is something I can read top to bottom in one sitting. For a personal site that is worth more than any feature I removed.
Até lá, o site inteiro é uma coisa que eu consigo ler de ponta a ponta de uma sentada. Para um site pessoal isso vale mais do que qualquer feature que eu tirei.