Use Cases (Atualizado: 02/06/2026)

Desenvolvimento Astro com Claude Code: Collections, SSG e validação

Guia prático para criar sites Astro com Claude Code: setup, posts, tags, hidratação e comandos de build.

Desenvolvimento Astro com Claude Code: Collections, SSG e validação

Por que Claude Code combina com Astro

Astro é uma ótima escolha para blogs, documentação, portfólios, páginas de produto e sites em que a maior parte do conteúdo é lida. Você pode usar componentes React, Vue ou Svelte, mas o Astro não transforma todas as páginas em uma aplicação pesada no cliente. A arquitetura de ilhas mantém conteúdo estático como estático e hidrata no navegador apenas as partes interativas, como busca, filtros ou botões.

Claude Code ajuda mais quando você pede para ele entender o projeto antes de editar. Em Astro, uma página depende de astro.config.mjs, src/content.config.ts, src/pages/, src/components/, imagens, rotas e comandos de build. Se Claude Code lê esses arquivos primeiro e explica o plano, as alterações ficam menores e dependências desnecessárias aparecem mais cedo.

Este guia usa o padrão atual de Content Collections do Astro: src/content.config.ts, astro/loaders e astro/zod. Confira as fontes oficiais antes de aplicar em produção: Claude Code Quickstart, Astro Content Collections, Astro template directives e Astro routing reference. Para decisões de arquitetura, veja também a comparação SSR/SSG e o guia de SEO.

Comece com um escopo claro

Um prompt como “crie um blog Astro” é amplo demais. Claude Code pode mudar design, rotas, modelo de conteúdo e dependências de uma vez. Defina o alvo: site estático de conteúdo, MDX, sitemap, frontmatter tipado, lista de posts, páginas de tags e validação por build.

npm create astro@latest my-astro-site
cd my-astro-site
npx astro add mdx sitemap tailwind
npm run dev

Depois, peça uma leitura antes da edição:

claude "Revise este projeto Astro como um site de conteúdo. Leia astro.config.mjs, src/content.config.ts, src/pages e src/components. Antes de editar, explique o plano de implementação e os comandos de verificação."

A configuração inicial pode ser pequena:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import tailwind from '@astrojs/tailwind';

export default defineConfig({
  site: 'https://example.com',
  output: 'static',
  integrations: [mdx(), sitemap(), tailwind()],
  markdown: {
    shikiConfig: {
      theme: 'github-dark',
    },
  },
});

Troque site pelo domínio real antes de publicar. Sitemap, URLs canônicas e parte do SEO dependem desse valor.

Defina Content Collections com a API atual

Content Collections transforma arquivos Markdown e MDX em dados com formato conhecido. Em vez de confiar que todo artigo terá o mesmo frontmatter, você define um schema e o Astro mostra erros antes do deploy. Isso é muito útil em sites multilíngues, onde uma tradução pode alterar por engano um campo fixo.

// src/content.config.ts
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';

const blog = defineCollection({
  loader: glob({
    base: './src/content/blog',
    pattern: '**/*.{md,mdx}',
  }),
  schema: z.object({
    title: z.string().max(80),
    description: z.string().max(120),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
    heroImage: z.string().optional(),
  }),
});

export const collections = { blog };

Um pedido de revisão específico funciona melhor:

claude "Revise src/content.config.ts para Astro 5. Verifique API atual de Content Collections, tamanho de description, filtro de draft, updatedDate opcional e mistura com APIs antigas."

Esse schema vira um contrato de publicação. Data inválida, descrição longa demais ou tags quebrado aparece antes do site ir ao ar.

Caso 1: lista de posts com paginação

O primeiro caso prático é o índice do blog. Não dependa da ordem retornada por getCollection(). Filtre rascunhos, ordene por data e passe as entradas para um componente de card.

---
// src/pages/blog/[...page].astro
import { getCollection } from 'astro:content';
import PostCard from '../../components/PostCard.astro';

export async function getStaticPaths({ paginate }) {
  const posts = (await getCollection('blog', ({ data }) => data.draft !== true))
    .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());

  return paginate(posts, { pageSize: 12 });
}

const { page } = Astro.props;
---

<section class="mx-auto max-w-5xl px-4 py-10">
  <h1 class="text-3xl font-bold">Blog</h1>
  <div class="mt-8 grid gap-6 md:grid-cols-2">
    {page.data.map((post) => <PostCard post={post} />)}
  </div>
  <nav class="mt-10 flex justify-between">
    {page.url.prev ? <a href={page.url.prev}>Previous</a> : <span />}
    {page.url.next ? <a href={page.url.next}>Next</a> : <span />}
  </nav>
</section>

O card pode ser direto:

---
// src/components/PostCard.astro
import type { CollectionEntry } from 'astro:content';

type Props = {
  post: CollectionEntry<'blog'>;
  lang?: string;
};

const { post, lang = 'pt' } = Astro.props;
const href = lang === 'ja' ? `/blog/${post.id}/` : `/${lang}/blog/${post.id}/`;
const date = post.data.updatedDate ?? post.data.pubDate;
---

<article class="rounded border border-slate-200 p-5">
  <p class="text-sm text-slate-500">
    <time datetime={date.toISOString()}>{date.toLocaleDateString('pt-BR')}</time>
  </p>
  <h2 class="mt-2 text-xl font-semibold">
    <a href={href}>{post.data.title}</a>
  </h2>
  <p class="mt-3 text-slate-700">{post.data.description}</p>
  <ul class="mt-4 flex flex-wrap gap-2">
    {post.data.tags.map((tag) => <li class="rounded bg-slate-100 px-2 py-1 text-xs">{tag}</li>)}
  </ul>
</article>

Esse padrão serve para três cenários comuns: blog técnico pessoal, base de conhecimento interna e changelog de produto. Nos três, preserve metadados antes de mexer no visual.

Caso 2: páginas de tags e hidratação seletiva

O segundo caso é o arquivo por tag. O erro comum é usar o nome do tag diretamente na URL. Espaços, maiúsculas e caracteres não latinos podem criar rotas frágeis. Separe slug de URL e label de exibição.

---
// src/pages/tags/[tag]/[...page].astro
import { getCollection } from 'astro:content';
import PostCard from '../../../components/PostCard.astro';

const tagSlug = (tag) =>
  encodeURIComponent(tag.toLowerCase().trim().replace(/\s+/g, '-'));

export async function getStaticPaths({ paginate }) {
  const posts = await getCollection('blog', ({ data }) => data.draft !== true);
  const groups = new Map();

  for (const post of posts) {
    for (const label of post.data.tags) {
      const slug = tagSlug(label);
      const group = groups.get(slug) ?? { slug, label, posts: [] };
      group.posts.push(post);
      groups.set(slug, group);
    }
  }

  return [...groups.values()].flatMap((group) =>
    paginate(group.posts, {
      params: { tag: group.slug },
      props: { tag: group.label },
      pageSize: 10,
    }),
  );
}

const { page, tag } = Astro.props;
---

<section class="mx-auto max-w-5xl px-4 py-10">
  <h1 class="text-3xl font-bold">Tag: {tag}</h1>
  <div class="mt-8 grid gap-6 md:grid-cols-2">
    {page.data.map((post) => <PostCard post={post} />)}
  </div>
</section>

O terceiro caso é uma busca. Não transforme a página inteira em aplicação cliente por causa de um componente:

---
// src/pages/index.astro
import Hero from '../components/Hero.astro';
import SearchBox from '../components/SearchBox.tsx';
import LatestPosts from '../components/LatestPosts.astro';
---

<Hero />
<SearchBox client:visible />
<LatestPosts />

client:load é para interação imediata. client:visible é melhor quando o componente pode esperar até entrar na tela.

Erros comuns e verificação

O primeiro erro é copiar tutoriais antigos de Content Collections. O segundo é pedir para melhorar o site inteiro de uma vez. O terceiro é esquecer heroImage, description e Open Graph. O quarto é achar que build verde basta para publicar. Confira também paginação, links internos, links externos, mobile e CTA.

npm run build
npx astro check
npm run preview

Se o build falhar, peça classificação antes de corrigir:

claude "Leia a falha de npm run build. Classifique como sintaxe Astro, schema de Content Collections, code fence de MDX, geração de rotas ou problema de links. Depois proponha o menor ajuste."

CTA e resultado testado

Quem está começando pode usar a folha de consulta gratuita. Quem precisa de modelos pode ver produtos. Para equipes que querem organizar um site Astro, regras de revisão e adoção do Claude Code, o caminho natural é treinamento e consultoria.

Na prática, Claude Code foi rápido para gerar arquivos .astro e conectar páginas às collections. Ainda assim, precisei revisar API atual do Astro, codificação segura de tags na URL, uso excessivo de client:load e execução real do build. O fluxo mais estável foi ler o projeto, limitar a mudança, comparar com a documentação oficial, rodar build e revisar o preview.

#Claude Code #Astro #framework #SSG #frontend
Grátis

PDF grátis: cheatsheet do Claude Code

Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.

Cuidamos dos seus dados e não enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.