Construindo o Mundo Nuvem do zero
Como criei este site estático com Astro 6, Tailwind CSS 4, Cloudflare Pages e Supabase — custo zero de hospedagem, PageSpeed verde, pronto para SEO.
O Mundo Nuvem é o próprio caso de uso que ele documenta. Este projeto registra cada decisão técnica, custo e aprendizado da construção do site — para que você possa replicar a mesma arquitetura nos seus projetos.
Custo de hospedagem: R$ 0,00/mês. Usando exclusivamente free tiers que escalam até tráfego real sem cobrar nada.
Decisões de arquitetura
A escolha de stack não foi aleatória. Cada ferramenta foi selecionada com base em três critérios: custo zero no free tier, performance nativa (HTML estático entregue por CDN) e fluxo de desenvolvimento via Git sem painel admin.
Por que Astro e não Next.js ou Gatsby
Astro é o único framework que foi construído para sites de conteúdo desde o início. Ele entrega zero JavaScript por padrão — o que significa que cada página é HTML puro quando não há interatividade necessária. Para um site editorial como o Mundo Nuvem, isso se traduz diretamente em Core Web Vitals verdes sem otimização manual.
Next.js é excelente para aplicações web. Para sites de conteúdo, é excessivo — você importa um runtime de React para renderizar texto estático.
Por que Cloudflare Pages e não Vercel ou Netlify
Cloudflare Pages tem o free tier mais generoso do mercado para sites estáticos: deploys ilimitados, largura de banda ilimitada e CDN com mais de 300 pontos de presença no mundo. A Vercel cobra por largura de banda no plano gratuito a partir de certo volume.
A decisão também abre caminho para usar Cloudflare R2 (armazenamento de assets sem custo de egress) e Cloudflare Pages Functions (serverless para a API de tracking) — tudo no mesmo ecossistema, sem configurar múltiplos provedores.
Por que Supabase apenas para Radar e newsletter
O conteúdo longo (projetos e guias) vive em arquivos MDX no repositório Git. Isso significa:
- Controle de versão gratuito para cada mudança de conteúdo
- Fluxo natural de escrita no VSCode com preview em tempo real
- Zero custo de banco de dados para o conteúdo principal
- Conteúdo indexável pelo Google desde o primeiro build
O Supabase entra apenas onde o banco de dados faz sentido: notícias do Radar (que mudam o dia todo) e e-mails de newsletter (que precisam de RLS e inserção server-side).
Fase 1 — Base técnica
Inicializando o projeto
npm create astro@latest mundo-nuvem -- --template minimal --typescript strict --no-git Após a criação, as dependências de produção:
npm install tailwindcss @tailwindcss/vite @astrojs/mdx @astrojs/sitemap @astrojs/rss Atenção importante: o npm pode instalar Vite 8 como dependência, o que quebra o @tailwindcss/vite 4.x pelo novo bundler Rolldown. A solução é forçar Vite 7 via overrides no package.json:
{
"overrides": {
"vite": "~7.3.2"
}
}
Tailwind CSS 4 — abordagem CSS-first
O Tailwind 4 abandonou o arquivo tailwind.config.js. A configuração agora vive inteira no CSS:
@import "tailwindcss";
@theme {
--color-mn-bg: #0a0e1a;
--color-mn-surface: #111827;
--color-mn-glow: #9bd9ff;
/* ... demais tokens */
}
E o plugin Vite substitui o antigo @astrojs/tailwind:
// astro.config.mjs
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
vite: { plugins: [tailwindcss()] },
});
Content Collections — Astro 6
O Astro 6 migrou para a Content Layer API. O arquivo de configuração das coleções saiu de src/content/config.ts para src/content.config.ts (na raiz do src/).
Cada coleção usa o glob loader:
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const projetos = defineCollection({
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/projetos' }),
schema: z.object({
title: z.string(),
description: z.string().max(160),
status: z.enum(['planejado', 'em-construcao', 'concluido']),
provider: z.array(z.string()),
stack: z.array(z.string()),
publishedAt: z.coerce.date(),
monthlyCost: z.string().optional(),
}),
});
Fase 2 — Conteúdo em Git
Rotas dinâmicas com getStaticPaths
A rota /projetos/[slug].astro usa getStaticPaths para gerar uma página por arquivo MDX:
export async function getStaticPaths() {
const projetos = await getCollection('projetos');
return projetos.map(entry => ({
params: { slug: entry.id },
props: { entry },
}));
}
O entry.id na Content Layer API do Astro 6 corresponde ao nome do arquivo sem extensão. Um arquivo construindo-o-mundo-nuvem.mdx gera a rota /projetos/construindo-o-mundo-nuvem.
JSON-LD para projetos: TechArticle + HowTo
O Google usa dados estruturados para entender o tipo de conteúdo. Para tutoriais técnicos, o schema TechArticle combinado com HowTo é o mais semântico:
const schema = [
{
'@type': 'TechArticle',
headline: title,
author: { '@type': 'Person', name: 'Fábio Silva' },
// ...
},
{
'@type': 'HowTo',
name: title,
step: headings
.filter(h => h.depth === 2)
.map((h, i) => ({
'@type': 'HowToStep',
position: i + 1,
name: h.text,
})),
},
];
Fase 3 — Supabase + Radar (próxima)
A próxima etapa conecta o banco de dados Supabase para o sistema de notícias do Radar. Os detalhes serão documentados quando a fase for concluída.
Custos reais do projeto
| Serviço | Plano | Custo mensal |
|---|---|---|
| Cloudflare Pages | Free | R$ 0,00 |
| Cloudflare R2 | Free (10 GB) | R$ 0,00 |
| Supabase | Free (500 MB, 50k req/mês) | R$ 0,00 |
| Domínio mundonuvem.com | Registro anual | ~R$ 7,00 |
Total de infraestrutura: R$ 7,00/mês (apenas o domínio).
Esta é a vantagem concreta do free tier bem escolhido: você escala para dezenas de milhares de pageviews mensais sem pagar nada de hospedagem.
O que aprendi
O maior aprendizado da Fase 1 não foi técnico — foi editorial. O tempo que vai para pensar a arquitetura de informação (quais URLs, quais schemas JSON-LD, como fazer interlinking) é diretamente proporcional ao SEO que você colhe 6 meses depois.
Sites que começam com “vou otimizar SEO depois” raramente otimizam. Construir o Seo.astro como componente obrigatório desde o dia 1 — com title, description, canonical e JSON-LD como props obrigatórias — eliminou esse débito antes que ele existisse.
Continue construindo
Explore outros projetos e guias do Mundo Nuvem: