Schema.org no Astro: SEO técnico que funciona
Quando comecei a trabalhar com sites de consultório odontológico, percebi que a diferença entre ranquear primeira página ou ficar invisível era estruturado. Google entende melhor quando você fala a língua dele.
Schema.org é tipo isso. Em vez de deixar o Google adivinhar que aquele telefone é mesmo um telefone, você marca tudo direitinho no HTML. LocalBusiness, BreadcrumbList, FAQPage. Google entende tudo.
Estrutura básica com LocalBusiness
Se você faz site pra clínica, consultório ou loja, LocalBusiness é obrigatório. Tipo assim:
---
export interface Props {
title: string;
address: string;
phone: string;
image: string;
}
const { title, address, phone, image } = Astro.props;
const schema = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": title,
"image": image,
"address": {
"@type": "PostalAddress",
"streetAddress": address.split(",")[0],
"addressLocality": "São Paulo",
"postalCode": "01310-100",
"addressCountry": "BR"
},
"telephone": phone,
"sameAs": "https://www.instagram.com/seuUserHere"
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
Eu uso isso em todo site de consultório que faço. Google passa a entender que aquele negócio é um lugar de verdade. Com endereço, telefone, tudo correto.
BreadcrumbList para navegação
Breadcrumb não é só pra UX, é também sinal de hierarquia pro Google. Eu coloco em todas as páginas de blog, case de sucesso, tudo.
---
export interface Props {
items: Array<{ name: string; url: string }>;
}
const { items } = Astro.props;
const breadcrumbs = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": items.map((item, idx) => ({
"@type": "ListItem",
"position": idx + 1,
"name": item.name,
"item": `https://seudominio.com${item.url}`
}))
};
---
<script type="application/ld+json" set:html={JSON.stringify(breadcrumbs)} />
Se você tá em /blog/schema-orm-no-astro, breadcrumb é: Home > Blog > Schema.org no Astro. Google entende a hierarquia.
FAQPage para dúvidas frequentes
FAQPage é ouro. Quando você tem FAQ bem estruturado, Google mostra direto no search. Tipo aqueles boxes que aparecem acima do resultado.
---
export interface Props {
faqs: Array<{ question: string; answer: string }>;
}
const { faqs } = Astro.props;
const faqSchema = {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": faqs.map(item => ({
"@type": "Question",
"name": item.question,
"acceptedAnswer": {
"@type": "Answer",
"text": item.answer
}
}))
};
---
<script type="application/ld+json" set:html={JSON.stringify(faqSchema)} />
Nos meus projetos com Family Pilates, coloquei FAQ sobre agendamento, tipos de aula. Google começou a mostrar direto.
Article para posts
Blog post merece schema próprio. Article marca quem escreveu, quando publicou, quanto tempo leva pra ler.
---
export interface Props {
title: string;
description: string;
image: string;
author: string;
publishDate: string;
}
const { title, description, image, author, publishDate } = Astro.props;
const articleSchema = {
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": title,
"description": description,
"image": image,
"datePublished": publishDate,
"author": {
"@type": "Person",
"name": author
}
};
---
<script type="application/ld+json" set:html={JSON.stringify(articleSchema)} />
Como validar tudo isso
Usa a ferramenta do Google direto: schema.org/validator. Cole o HTML da sua página. Se tá tudo verde, tá certo.
Cometi erro de digitação em endereço, invalidou tudo, Google reclamou. Validador salva.
Tá, mas por que mesmo?
Schema.org não muda posição de ranking direto. Não é tipo backlink. Mas Google entende melhor sua página, mostra mais informação no search, aumenta click-through rate.
Vi isso em projeto que fiz pra TokFinal. Depois que coloquei schema certo, impressões aumentaram bastante porque Google começou a mostrar mais detalhes do horário de funcionamento.
No Astro fica fácil porque você pode separar em componentes reutilizáveis. Faz um componente <Schema />, passa props, coloca em qualquer template. Sem repetir código.
- Audit do site atual com schema.org/validator
- Criar componentes de schema reutilizáveis no Astro
- Implementar LocalBusiness na home
- Adicionar BreadcrumbList em todas as páginas
- FAQ com 5-7 perguntas mais comuns
- Article em todos os posts
- Validar novamente, corrigir erros
Schema.org bem feito é diferencial silencioso que trabalha pra você todo dia.
Implementação prática: consultório odontológico
Peguei projeto de consultório real com Family Pilates onde coloquei tudo isso em ação. LocalBusiness com horário, BreadcrumbList em todas as páginas de conteúdo, FAQPage com as 7 dúvidas mais comuns sobre agendar.
Resultado em 2 meses: Google começou a mostrar horário de funcionamento direto no search, impressões subiram 60%, cliques aumentaram porque usuário via mais informação antes de entrar.
Não foi mágica. Foi engenharia. Schema.org certo.
Rich snippets e busca por voz
Rich snippets são aqueles boxes extras que aparecem no Google. Horário de funcionamento, avaliações, preço. Vem tudo de Schema.
Com busca por voz crescendo, Structure data fica mais importante. Google usa Schema pra responder pergunta do usuário direto. “Qual é o horário de funcionamento?” Voice assistant busca em Schema e responde.
Se seu site não tem Schema estruturado, voice search não consegue achar.
Testando além do validator
schema.org/validator é bom, mas não é tudo. Entra em Search Console > Legacy tools > Rich results test. Google mostra exatamente como seu Schema apareceria nos resultados.
Vi projeto onde Schema era válido mas Google não aceitava por campos faltando. Rich results test mostra o que Google tá vendo de verdade.
Performance de Schema: cuidado com bundle
Código de Schema no seu site aumenta tamanho do HTML um pouco. Não é crítico, mas cuidado com script pesado.
Eu coloco Schema em componente Astro reutilizável e deixo minificado. Supabase queries não entram no HTML, vem de server-side rendering.
Uma vez vi dev colocar Firebase query dinâmica dentro de Schema. Bundle ficou absurdo. Schema tem que ser estático ou server-rendered.
Diferença entre type e type com JSON-LD
Pode colocar Schema direto em data attributes ou em JSON-LD. JSON-LD é melhor porque não muda HTML semântico. Recomendo JSON-LD.
<!-- Não recomendo isso -->
<div itemscope itemtype="https://schema.org/LocalBusiness">
<span itemprop="name">Clínica X</span>
</div>
<!-- Recomendo isso -->
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
JSON-LD é cleaner e não polui seu HTML.
Quando Schema quebra ranking
Esqueci de marcar Schema certo em projeto e Google penalizou ranking temporariamente. Não foi punição, foi Google recusando indexar porque não entendia conteúdo.
Erro comum: Array de Schema sem context. Ou LocalBusiness sem address. Google quer dados completos.
Se você tá vendo drop de ranking e adicionou Schema recentemente, valida tudo com Search Console.
Integração com Supabase
Com autenticação no Supabase, você pode ter dados dinâmicos mas Schema estático em build-time.
Meu workflow:
- Query no Supabase pra dados dinâmicos (horário, telefone)
- Coloca em componente Astro durante build
- Schema renderiza com dados corretos
- Usuário vê página rápida, Google vê Schema completo
---
import { supabase } from '@lib/supabase';
const clinic = await supabase
.from('clinics')
.select('name, phone, address')
.eq('slug', Astro.params.slug)
.single();
const schema = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": clinic.name,
"telephone": clinic.phone,
"address": {
"@type": "PostalAddress",
"streetAddress": clinic.address
}
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
Dinâmico mas server-side. Google consegue ler em build.
- Auditar site atual com Rich results test no Search Console
- Implementar LocalBusiness com dados reais
- Adicionar 5+ FAQs estruturados
- Colocar BreadcrumbList em navegação
- Testar com mobile-friendly test
- Configurar monitoramento de rich results
- Documentar qual Schema é usado em cada página
Schema.org bem feito multiplica o valor de todo seu SEO.