Site rápido que a IA lê: o que pedir ao seu programador
Página cheia de código demora para abrir, e o assistente de IA não consegue ler. Uma ferramenta chamada Astro entrega texto pronto e leve. Este guia é o que pedir ao seu programador.
Alexandre Caramaschi
Founder da Brasil GEO, ex-CMO da Semantix (Nasdaq), cofundador da AI Brasil
Este guia é para o dono de uma loja de moda, joalheria ou cosméticos. Ele explica por que uma página de guia ou de comparação demora para abrir e some das respostas dos assistentes de IA. Você vai entender o que pedir ao seu programador, sem escrever código nenhum.
O nome dessa ferramenta é Astro. A ideia é simples: a maior parte do conteúdo de uma loja, como guias e páginas de marca, fica igual de um clique para o outro. Tratar esse conteúdo como texto pronto, em vez de programa pesado, é o que o deixa rápido e fácil de ler para uma máquina. Os exemplos a seguir mostram como isso se aplica à sua loja e ao GEO. GEO é fazer o ChatGPT e o Google citarem o seu negócio na resposta.
Por que o Astro deixa o conteúdo da loja rápido?
Porque ele entrega a página já pronta, em texto, sem mandar código para o navegador montar. O cliente vê a página quase na hora, e o robô da IA lê sem precisar rodar programa nenhum.
A diferença começa no padrão de fábrica. As ferramentas voltadas a aplicativo presumem que tudo é interativo e mandam o motor junto com a página. O Astro presume o contrário: o conteúdo vai pronto, e o código só entra onde existe interação de verdade. Para um blog de marca, uma central de ajuda ou um guia de produto, isso significa páginas que abrem quase na hora.
Esse ponto vale dinheiro em GEO. Um robô de IA que precisa rodar código para enxergar o texto lê menos e confia menos no que leu. Página pronta, servida de primeira, é o jeito mais barato de garantir que o assistente leia a ficha do produto e o texto do guia. A mesma escolha que o cliente sente como velocidade a máquina sente como clareza.
Framework de aplicação e Astro
Framework de aplicação
- Assume que tudo é interativo
- Envia o runtime para o navegador montar a página
- Carrega megabytes de JavaScript que ninguém pediu
- O crawler de IA precisa executar script para ler o conteúdo
Astro, content-first
- O conteúdo é HTML pronto, servido de primeira
- JavaScript só entra onde há interação real
- Páginas abrem quase instantaneamente, com Core Web Vitals saudáveis
- Cliente e crawlers de IA leem sem executar script
---
// src/pages/guias/[slug].astro — frontmatter roda no servidor, no build
import Layout from "../../layouts/Layout.astro";
import { getCollection, getEntry } from "astro:content";
export async function getStaticPaths() {
const guias = await getCollection("guias");
return guias.map((g) => ({ params: { slug: g.id } }));
}
const { slug } = Astro.params;
const guia = await getEntry("guias", slug);
const { Content } = await guia.render();
---
<Layout titulo={guia.data.titulo}>
<article>
<h1>{guia.data.titulo}</h1>
<Content />
</article>
</Layout>
O bloco entre os traços é código que roda no servidor na hora de montar o site, nunca no navegador do cliente. Ele busca o conteúdo, escolhe o que mostrar e devolve a página pronta. O que chega ao navegador é texto e marcação, sem motor de framework. Esse é o comportamento padrão da ferramenta.
O que o frontmatter faz durante o build
- getStaticPaths lista a coleçãoBusca a coleção de guias e gera um caminho por slug.
- getEntry escolhe o conteúdoRecupera o guia pelo slug e chama render() para obter o Content.
- Layout monta a páginaTítulo, article e Content viram HTML no servidor.
- O navegador recebe texto e marcaçãoSem o runtime de nenhum framework: rápido e indexável de saída.
A pergunta que muda o projeto é quanto código esta página precisa mesmo entregar. O Astro responde com zero, e você devolve só o necessário.
O que são as ilhas e por que só elas devem pesar?
A página inteira vai como texto pronto, e só pedaços pontuais recebem código, onde existe interação. Esses pedaços são as ilhas. Uma instrução chamada client:* decide quando cada ilha ganha vida.
Cenário: uma joalheria monta a página de uma coleção. O cabeçalho e a grade de produtos são fixos. O filtro lateral, o carrossel de destaques e o botão de favoritar são interativos. Em vez de dar vida à página toda, ela marca só esses três como ilhas e escolhe a instrução conforme a urgência de cada um.
Estático ou ilha na página de coleção
---
// src/pages/colecao/verao.astro
import FiltroPreco from "../../components/FiltroPreco.jsx";
import CarrosselDestaques from "../../components/CarrosselDestaques.jsx";
import MenuMobile from "../../components/MenuMobile.jsx";
import BotaoFavoritar from "../../components/BotaoFavoritar.jsx";
---
<MenuMobile client:media="(max-width: 768px)" />
<BotaoFavoritar client:load produtoId="anel-ouro-18k" />
<CarrosselDestaques client:visible />
<FiltroPreco client:idle />
Cada instrução resolve um caso concreto da loja. client:load liga o botão de favoritar na hora, porque o cliente pode clicar de cara. client:idle espera o navegador ficar ocioso para ligar o filtro de preço, que nunca é a primeira ação. client:visible segura o carrossel de destaques até ele aparecer na tela. E client:media só liga o menu do celular quando a tela é pequena, poupando o computador de baixar código que nunca usaria.
Qual diretiva client:* usar em cada ilha
- SeO cliente pode clicar logo de cara, como no botão de favoritarentãoclient:load hidrata imediatamente
- SeFica fora da primeira ação de qualquer visitante, como o filtro de preçoentãoclient:idle espera o navegador ficar ocioso
- SeO bloco está abaixo da dobra, como o carrossel de destaquesentãoclient:visible segura até entrar na viewport
- SeSó faz sentido numa faixa de tela, como o menu mobileentãoclient:media hidrata quando a media query bate
Existe ainda client:only, para componentes que não devem ser renderizados no servidor:
---
import MapaLojas from "../../components/MapaLojas.jsx";
---
<!-- renderiza apenas no cliente, sem HTML de servidor -->
<MapaLojas client:only="react" />
O client:only manda o Astro pular a montagem no servidor e montar o componente só no navegador. É a saída certa para algo que depende de recursos do próprio navegador, como um mapa de lojas que usa a localização. Em troca, esse pedaço não aparece no texto inicial da página.
Evite usá-lo em conteúdo que precisa ser lido pelo robô. A regra de GEO é simples: o que importa para ser encontrado fica pronto; o que é só comportamento vira ilha.
Como mostrar preço de cliente logado sem deixar a página lenta?
Com as ilhas de servidor. Você marca o bloco pessoal com server:defer e mostra um espaço reservado enquanto ele carrega. A página de catálogo continua pronta e guardada, e só o pedaço personalizado é calculado a cada visita.
Esse é o nó clássico da loja. A página do produto é a mesma para todo mundo e merece ficar em cache, ou seja, servida de uma cópia pronta. Já o preço do cliente logado, o estoque da loja mais perto e as recomendações são pessoais. Montar a página inteira a cada visita joga a cópia pronta fora.
O que é pessoal na página de produto
---
// src/components/PrecoLogado.astro — roda no servidor, por requisição
const { sku } = Astro.props;
const oferta = await buscarPrecoDoCliente(sku, Astro.request);
---
<p class="text-2xl font-bold text-ink">
{oferta.precoFormatado}
{oferta.clube && <span class="text-primary">preço de clube</span>}
</p>
---
// src/pages/produto/[sku].astro — página cacheável e estática
import PrecoLogado from "../../components/PrecoLogado.astro";
const { sku } = Astro.params;
---
<h1>Anel solitário ouro 18k</h1>
<PrecoLogado server:defer sku={sku}>
<span slot="fallback" class="skeleton">Carregando preço...</span>
</PrecoLogado>
A página do produto continua pronta e guardada: serve rápido para todo visitante e para o robô. O bloco do preço logado é montado à parte, no servidor, e encaixado quando fica pronto. Enquanto isso, o cliente vê o espaço reservado. Você mantém a velocidade do catálogo e ainda entrega o bloco personalizado.
Quem faz o quê com Server Islands
Dá para ter interação sem carregar um framework inteiro?
Dá. Um bloco de código dentro do próprio componente do Astro vira uma ilha de comportamento, empacotada pela ferramenta, sem framework nenhum. Você só instala React ou Svelte quando quer mesmo um componente desses.
Muita interação de loja é simples: abrir uma pergunta frequente, copiar um cupom, trocar a aba entre descrição e ficha técnica. Para isso, framework é peso morto. O Astro empacota o bloco do componente como um módulo isolado.
---
// src/components/CupomCopiavel.astro
const { codigo } = Astro.props;
---
<button class="cupom" data-codigo={codigo}>
Copiar cupom {codigo}
</button>
<script>
document.querySelectorAll<HTMLButtonElement>(".cupom").forEach((btn) => {
btn.addEventListener("click", async () => {
await navigator.clipboard.writeText(btn.dataset.codigo ?? "");
btn.textContent = "Cupom copiado";
});
});
</script>
<style>
.cupom {
background: var(--color-primary);
color: var(--color-on-primary);
padding: 0.5rem 1rem;
border-radius: 0.5rem;
}
</style>
Três coisas acontecem nesse arquivo. O bloco de código vira JavaScript simples, empacotado, sem motor de framework. O bloco de estilo vale só dentro do componente, então a classe .cupom não vaza para o resto do site. E repare no contraste: o botão usa um par de cores pensado para atender à norma de acessibilidade, em vez de uma cor solta.
As três peças do CupomCopiavel.astro
Quando você de fato precisa de um componente de framework, por exemplo um seletor de variações complexo já escrito em React, o caminho é explícito:
# adiciona a integração antes de usar componentes de framework como ilhas
npx astro add react
# ou, para Svelte
npx astro add svelte
Sem instalar a integração, um componente em React ou Svelte não é reconhecido como ilha, e a instrução client:* não faz efeito. A ordem importa: primeiro a integração, depois o componente. Para a maior parte do conteúdo de loja, porém, a ilha simples basta e mantém o código no chão.
Script vanilla ou framework
- SeAcordeão de perguntas, cupom copiável, aba de descrição e fichaentãoO script do componente .astro basta e mantém o JavaScript no chão
- SeSeletor de variações complexo já escrito em ReactentãoPrimeiro npx astro add react, depois o componente com a diretiva client:*
- SeComponente .jsx ou .svelte sem a integraçãoentãoNão é reconhecido como ilha e a diretiva client:* não tem efeito
Como impedir que uma ficha incompleta vá ao ar?
Descrevendo o formato esperado de cada guia e conferindo tudo na hora de montar o site. Se um campo faltar ou vier no tipo errado, o site não sobe, e o erro aparece antes de o cliente ver.
A loja com dezenas de guias, fichas e páginas de marca precisa garantir que cada peça tenha título, resumo dentro do limite, data e tópicos. Sem essa conferência, o campo que faltou só aparece com a página já no ar. Ela sobe quebrada ou invisível para o SEO (fazer o Google mostrar o seu negócio quando alguém procura).
// src/content.config.ts
import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders";
const guias = defineCollection({
loader: glob({ pattern: "**/*.mdx", base: "./src/content/guias" }),
schema: z.object({
titulo: z.string(),
subtitulo: z.string(),
resumo: z.string().max(320),
pilar: z.string(),
topicos: z.array(z.string()),
publicadoEm: z.coerce.date(),
leituraMin: z.number(),
destaque: z.boolean().default(false),
}),
});
export const collections = { guias };
A varredura passa pelos arquivos da pasta de guias, e o formato descreve o que cada um precisa ter. Se um resumo passar do limite, se faltar o campo de pilar ou se o tempo de leitura vier como texto, a montagem falha e aponta o arquivo. Nenhuma página malformada chega ao ar, e o time edita sem medo de derrubar a busca em silêncio.
Do arquivo .mdx à página validada
- O loader glob varre a pastaCada arquivo .mdx de guias entra na coleção.
- O schema Zod descreve o frontmatterTítulo, subtítulo, resumo até 320 caracteres, pilar, tópicos, data, leitura e destaque.
- O build validaCampo faltando ou tipo errado quebra o build com erro apontando o arquivo.
- getCollection devolve itens tipadosA página de índice filtra, ordena e renderiza sem parse manual.
A leitura é igualmente simples e tipada:
// listagem de guias, com tipos derivados do schema
import { getCollection } from "astro:content";
const guias = await getCollection("guias");
const emDestaque = guias.filter((g) => g.data.destaque);
const ordenados = guias.sort(
(a, b) => b.data.publicadoEm.valueOf() - a.data.publicadoEm.valueOf(),
);
A leitura devolve os itens já conferidos, com cada campo no tipo certo. A página de índice de guias filtra, ordena e mostra sem precisar interpretar nada na mão. Para a loja, essa disciplina é o que mantém o conteúdo pronto para o robô: dado coerente, datado e completo.
Sem e com Content Collections
Sem validação
- Campo faltando só aparece com a página no ar
- Página quebrada ou sem SEO em silêncio
- Parse manual de frontmatter em cada listagem
Com Content Collections
- Frontmatter inconsistente quebra o build, e a página publicada fica intacta
- Erro claro apontando o arquivo
- Dados coerentes, datados e completos: camada agent-ready
Como acabar com a cor da marca espalhada por dezenas de arquivos?
Guardando as cores num único bloco de tema. Cada cor vira ao mesmo tempo uma variável e uma classe pronta para usar. Isso garante o contraste exigido pela norma de acessibilidade e acaba com o mesmo azul repetido em trinta arquivos.
O Tailwind na versão 4 deixa o tema morar dentro do próprio CSS. A escala de cor escolhida é a OKLCH, porque nela mudar o brilho gera uma variação que o olho percebe como uniforme. Isso facilita acertar os pares de contraste.
Do token em @theme à classe utilitária
- 1Escala OKLCH 50 a 950--color-primary-50, -500 e -900 com a luminosidade caindo.
- 2Papéis de cor--color-primary, --color-on-primary, --color-ink e --color-surface.
- 3Variável CSSUsável em qualquer style ou inline.
- 4Classe utilitária geradabg-primary, text-ink, bg-surface.
- 5Tema escuro:root[data-theme=dark] troca --color-ink e --color-surface por variável que adapta.
/* src/styles/global.css */
@import "tailwindcss";
@theme {
/* escala primária em OKLCH: lightness cai do 50 ao 950 */
--color-primary-50: oklch(0.97 0.02 265);
--color-primary-500: oklch(0.62 0.17 265);
--color-primary-900: oklch(0.32 0.12 265);
/* pares de papel, pensados para WCAG AA */
--color-primary: var(--color-primary-500);
--color-on-primary: oklch(0.99 0 0); /* texto sobre primário */
--color-ink: oklch(0.22 0.01 265); /* texto principal */
--color-surface: oklch(0.99 0 0); /* fundo claro */
}
/* dark: troca por variável que adapta, nunca hex escuro fixo */
:root[data-theme="dark"] {
--color-ink: oklch(0.95 0.01 265);
--color-surface: oklch(0.20 0.02 265);
}
Cada cor declarada no bloco de tema faz duas coisas ao mesmo tempo. Ela existe como variável, usável em qualquer estilo, e gera uma classe pronta, como a de fundo ou a de texto. É isso que resolve o azul espalhado por trinta arquivos: a cor da marca passa a ter um ponto único. Trocar o tom da loja vira editar uma linha.
O contraste deixa de ser sorte. Os pares de tinta e de fundo já nascem pensados para atingir 4,5:1 no texto normal e 3:1 no texto grande. O time aplica a dupla confiando que passa na norma. No tema escuro, a mesma variável se adapta, em vez de um valor fixo que sumiria sobre fundo escuro. Esse cuidado é o que mantém o conteúdo legível para gente e para máquina.
Qual é o próximo passo para a sua loja?
O caminho prático é começar pequeno. Peça ao seu programador uma camada de conteúdo em Astro, separada do checkout, que entregue texto pronto por padrão. Peça também que ele confira os dados de cada guia antes de publicar. E que dê vida só aos pedaços com interação, isole o que é pessoal do cliente e guarde as cores num só lugar.
Seis movimentos para a camada de conteúdo
- Projeto Astro só para o conteúdo premiumSeparado do storefront transacional.
- HTML estático por padrãoRápido para o cliente e legível por crawler.
- Guias e fichas como Content CollectionsCom schema Zod validado no build.
- Hidratar só as ilhasCom a diretiva client:* adequada a cada interação.
- Isolar o pessoal com Server IslandsPreço logado e recomendações fora do cache da página.
- Marca em tokens OKLCH dentro de @themeContraste garantido e cor com um único ponto de verdade.
A joalheria do cenário não trocou a loja inteira. Ela separou o conteúdo, deixou o texto pronto e ganhou páginas rápidas que o assistente de IA consegue ler. O passo de hoje é escolher qual ferramenta cuida de qual parte da loja. O guia comparativo de stack de frontend para e-commerce mostra quando usar Astro, Next e Svelte.
Onde o Astro entra na composição da loja
- SeBlog de marca, central de ajuda, comparação ou guia de produtoentãoCamada de conteúdo premium em Astro, estática e citável
- SeStorefront transacional, com login, carrinho e checkoutentãoOutra peça da composição: veja o comparativo entre Astro, Next e Svelte
Perguntas frequentes
Vale usar o Astro se a minha loja já roda numa plataforma pronta?
Vale, porque a camada de conteúdo (guias, comparativos, páginas de marca, central de ajuda) não precisa do peso de um sistema de aplicativo inteiro. O Astro entrega esse conteúdo como texto pronto e rápido, sem mandar código junto, o que melhora a velocidade e facilita a leitura pelos robôs de IA. A loja de venda continua onde está.
Qual a diferença entre client:load, client:idle e client:visible?
São três momentos para ligar uma ilha. O client:load liga na hora do carregamento, bom para algo crítico no alto da página. O client:idle espera o navegador ficar ocioso, bom para interação secundária. O client:visible só liga quando o bloco aparece na tela, o que economiza código em carrossel, filtro e tudo o que fica embaixo.
Como mostrar preço logado sem perder a página guardada em cache?
Com ilhas de servidor. Um bloco marcado com server:defer é montado à parte, enquanto a página segue guardada e pronta. Enquanto o bloco não chega, o cliente vê um espaço reservado. Assim o catálogo serve rápido para todo mundo e só o pedaço personalizado é calculado a cada visita.
Preciso de React ou Svelte para ter interação no Astro?
Nos casos simples você não precisa disso. Um bloco de código dentro do próprio componente do Astro vira uma ilha de comportamento, empacotada pela ferramenta, sem framework. Você só instala a integração quando quer mesmo usar componentes de React ou Svelte como ilhas.
Por que guardar as cores da marca num bloco de tema ajuda a loja?
Porque cor solta em cada arquivo é o que gera marca inconsistente e falha de contraste. Um bloco de tema faz cada cor virar ao mesmo tempo variável e classe pronta. Ele garante o contraste da norma de acessibilidade e deixa o tema escuro adaptar sozinho, sem espalhar valor fixo pelo código.
Para levar deste guia
-
O Astro entrega a página pronta, como texto, em vez de mandar o navegador montar tudo na hora. Ela carrega rápido e o robô de leitura da IA (o crawler) consegue ler sem travar.
-
Só os pedaços da página que realmente precisam de interação (chamados de ilhas) recebem código pesado. O resto fica leve. Isso evita carregar coisa que o cliente nunca vai usar.
-
Dá para manter a página do produto rápida e pronta para todo mundo, e ainda mostrar preço de cliente logado e recomendação, sem misturar as duas coisas.
-
O sistema confere se cada guia e ficha de produto tem os dados certos antes de publicar. Se faltar algo, o erro aparece antes de a página ir ao ar.
-
As cores da marca ficam guardadas num único lugar do sistema. Trocar o tom vira uma linha só de código, em vez de caçar a mesma cor espalhada em dezenas de arquivos.
De onde vêm os números deste guia?
Cada link abre a publicação de origem, com o nome de quem assina o dado e a data em que ele saiu.
- W3C, Web Content Accessibility Guidelines 2.2, critério de contraste mínimo, 12 de dezembro de 2024.
- Curadoria Brasil GEO, Alexandre Caramaschi, 2026.
Cursos para aprofundar
Formações gratuitas do portal de educação de Alexandre Caramaschi, fundador da Brasil GEO.
SEO Técnico para E-commerce
Core Web Vitals, renderização e crawl budget: o que a stack do storefront precisa entregar para ranquear e ser citada.
Curso gratuitoCRO e Experimentação
Governança de experimentos e testes A/B para evoluir a interface sem quebrar a conversão a cada release da stack.
Leve a decisão para o seu contexto
Este guia dá o mapa; a sua operação dá os números. As calculadoras do portal fazem a conta com os seus dados. A Onclick mostra como um sistema de retaguarda, o que fica por trás do caixa, sustenta o dia a dia.