GEO, Schema e JSON-LD para Ser Citado por Motores de LLM

By Brenner Cruvinel • 19 minutes read

geo, schema e json-ld pra engine llm-ready

como estruturar schema pra ser citado por motor generativo (AI Overviews, Perplexity, ChatGPT), não só pra rich result do google. o ponto que muda tudo no fim: json-ld limpo deixou de ser comida de crawler, virou o input que o NLWeb consome e devolve.

a arquitetura central: @graph e @id

a diferença entre amador e estado da arte: blocos isolados de json-ld soltos versus um único grafo conectado. cada entidade declarada uma vez, com @id estável, e todo o resto referenciando por { "@id": "..." }. um único bloco @graph por página, não múltiplos scripts brigando.

regra de ancoragem do @id (convergência dos guias de 2026 e do W3C JSON-LD Best Practices):

entidades persistentes do site, que valem em todas as páginas, ancoram na raiz do domínio com fragmento. Organization em dominio.com/#organization. WebSite em dominio.com/#website. Person dos autores em dominio.com/#nome.

entidades de página ancoram na URL da própria página mais fragmento. Article em dominio.com/artigo#article. WebPage em dominio.com/artigo#webpage. BreadcrumbList em dominio.com/artigo#breadcrumb. a entidade de página referencia as persistentes por @id, nunca duplica o objeto.

ordem importa pra parser menos sofisticado: declare as persistentes (Organization, WebSite, Person) antes das de página (WebPage, Article, BreadcrumbList). não é requisito W3C, é higiene de engenharia pra um parser linear resolver os nós na ordem certa.

os três bugs clássicos de auditoria, todos evitáveis com @id disciplinado:

concordância tripla (o GEO-16 coloca HTML semântico acima até de dados estruturados na correlação com citação): o texto visível, o HTML semântico (headings, listas, tabelas) e o json-ld precisam dizer a mesma coisa. schema que descreve conteúdo não visível na página é ignorado na melhor hipótese, sinal de spam na pior.

tipos de schema por atividade e prioridade em ia

fundação quase onipresente: Organization ou LocalBusiness pra entidade da marca, WebSite (declara o site e o SearchAction), WebPage por página ligando ao WebSite e à mainEntity, Person pra autores e porta-vozes, BreadcrumbList refletindo a arquitetura.

atividadetipos primáriosadições prioritárias 2026
site editorial, blogArticle, BlogPosting, NewsArticleSpeakableSpecification, Claim
e-commerceProduct, Offer, AggregateRating, ReviewDataset pra catálogo
negócio localLocalBusinessDefinedTerm pra serviços
saas, softwareSoftwareApplication, ServiceDataset pra changelog, NLWeb /ask
docs, base de conhecimentoTechArticle, HowTo, DatasetDefinedTermSet, NLWeb /ask
conteúdo de autoridade, pesquisaArticle, PersonStatement, Claim, ClaimReview
vídeo próprioVideoObjectponte pra entidade do canal

hierarquia de prioridade pra visibilidade em ia:

tipoimpacto em citação iarich result googleprioridade
Organization + sameAs Wikidatafundação do grafoindireto1
FAQPagealto pra extraçãodepreciado maio 20262
Article, BlogPostingaltoDiscover, Top Stories3
BreadcrumbListmédio-altobreadcrumb visual4
Product + Offeralto em e-commercerich result ativo5
DefinedTermautoridade semânticanenhum6
Datasetalto pra conteúdo com dadosnenhum7

tipos novos e subusados que valem o esforço: DefinedTerm e DefinedTermSet (glossários e vocabulário técnico de nicho, registra termo proprietário no grafo e desambigua o que não existe no Wikidata, extremamente subutilizado, é como você se firma como referência definitiva de um termo). Dataset (virou tipo de primeira classe porque alimenta pipeline RAG diretamente, todo artigo com tabela de métrica deveria declarar um nó Dataset referenciado pelo Article, com license e temporalCoverage). Claim, Statement, ClaimReview (crescendo com fact-checking integrado a llm, pra conteúdo editorial e de pesquisa). SoftwareSourceCode (marca conteúdo como referência técnica, não editorial). VideoObject (subestimado, o youtube é uma das fontes mais citadas por ia). SpeakableSpecification (sinaliza qual trecho do html é mais adequado pra extração direta, via cssSelector, vai no Article ou WebPage apontando pro resumo e os H2).

o @graph de referência

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://exemplo.com/#organization",
      "name": "Exemplo",
      "url": "https://exemplo.com",
      "sameAs": ["https://www.wikidata.org/wiki/Q000000"],
      "knowsAbout": ["generative engine optimization", "schema.org", "json-ld"]
    },
    {
      "@type": "WebSite",
      "@id": "https://exemplo.com/#website",
      "url": "https://exemplo.com",
      "publisher": { "@id": "https://exemplo.com/#organization" },
      "potentialAction": {
        "@type": "SearchAction",
        "target": "https://exemplo.com/busca?q={query}",
        "query-input": "required name=query"
      }
    },
    {
      "@type": "Person",
      "@id": "https://exemplo.com/#alberto",
      "name": "Alberto",
      "sameAs": ["https://www.wikidata.org/wiki/Q000001"],
      "knowsAbout": ["arquitetura de dados", "llm tooling"]
    },
    {
      "@type": "WebPage",
      "@id": "https://exemplo.com/artigo#webpage",
      "url": "https://exemplo.com/artigo",
      "isPartOf": { "@id": "https://exemplo.com/#website" },
      "speakable": {
        "@type": "SpeakableSpecification",
        "cssSelector": [".resumo", "h2"]
      }
    },
    {
      "@type": "Article",
      "@id": "https://exemplo.com/artigo#article",
      "headline": "titulo do artigo",
      "isPartOf": { "@id": "https://exemplo.com/artigo#webpage" },
      "author": { "@id": "https://exemplo.com/#alberto" },
      "publisher": { "@id": "https://exemplo.com/#organization" },
      "datePublished": "2026-06-15",
      "dateModified": "2026-06-15",
      "mentions": [{ "@id": "https://exemplo.com/artigo#dataset-metricas" }]
    },
    {
      "@type": "Dataset",
      "@id": "https://exemplo.com/artigo#dataset-metricas",
      "name": "metricas de schema e citacao por IA 2026",
      "isPartOf": { "@id": "https://exemplo.com/artigo#article" },
      "license": "https://creativecommons.org/licenses/by/4.0/",
      "temporalCoverage": "2024/2026"
    },
    {
      "@type": "BreadcrumbList",
      "@id": "https://exemplo.com/artigo#breadcrumb",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "home", "item": "https://exemplo.com" },
        { "@type": "ListItem", "position": 2, "name": "artigo", "item": "https://exemplo.com/artigo" }
      ]
    }
  ]
}

leia esse grafo como um banco de entidades, não uma lista de tags. Organization, WebSite e Person existem uma vez. WebPage e Article apontam pra elas. Dataset pendura no Article. é isso que um motor generativo costura quando monta a resposta e decide a quem atribuir.

implementação por plataforma

o princípio que não muda: o @graph é artefato de dados, não de UI. serializado uma vez a partir da fonte da verdade, presente onde o consumidor olha antes de qualquer execução de cliente. pra web, o consumidor é um crawler que lê o html inicial, então json-ld no html que chega antes do js rodar, server-side sempre, nunca via useEffect ou componentDidMount. pra nativo, não existe crawler lendo a tela do app, o vetor é o endpoint que o backend expõe (NLWeb /ask e /mcp).

fonte da verdade comum: modele o domínio como entidades e relações, não como páginas. defina tipos com schema de validação na linguagem do backend (JSON Schema, Pydantic em python, Zod ou schema-dts em ts, serde em rust, Codable em swift, kotlinx.serialization em kotlin). cada entidade com identificador interno estável que mapeia um a um pro @id. registre provenance, data de atualização, idioma e flags de confiança, que servem tanto pro json-ld quanto pro RAG. centralize a geração num módulo único (ex lib/schema), funções puras que recebem a entidade interna e devolvem o objeto json-ld validado. é esse módulo que mata a duplicação de plugin.

next.js (app router, padrão atual): schema em server component, nunca client component. schema-dts é o pacote oficial do google oss, type-only, sem custo de runtime, cerca de 100 mil downloads/semana, compatível com schema.org v30, suporta @graph e @id stubs. dois layers: layout raiz (app/layout.tsx) pras persistentes, page component pras de página. pra blog e editorial prefira SSG ou ISR sobre SSR puro, o schema é gerado no build ou na revalidação. next-seo + schema-dts cobre a maioria dos casos.

// app/blog/[slug]/page.tsx, Server Component
import type { Graph, WithContext } from 'schema-dts'
export default async function ArticlePage({ params }) {
  const post = await getPost(params.slug)
  const schema: WithContext<Graph> = {
    '@context': 'https://schema.org',
    '@graph': [{
      '@type': 'Article',
      '@id': `https://exemplo.com/blog/${params.slug}#article`,
      headline: post.title,
      author: { '@id': 'https://exemplo.com/#alberto' },
      publisher: { '@id': 'https://exemplo.com/#organization' },
      datePublished: post.publishedAt,
      dateModified: post.updatedAt,
    }],
  }
  return (
    <>
      <script type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }} />
    </>
  )
}

spa pura (vite, cra): problema não resolvido de forma confiável, a maioria dos crawlers de ia não executa js. conteúdo estático vai direto no index.html ou via react-helmet-async no build. conteúdo dinâmico precisa de pre-rendering (Prerender.io, Rendertron) ou migração pra meta-framework com ssr. backends de outras linguagens (rails, django, laravel, go, php): idêntico, gere o @graph no servidor e imprima a tag script no template antes de servir.

rust e wasm, dois cenários: rust no servidor (axum, actix, leptos ssr) é o caso fácil e mais forte. modele as entidades com serde, derive Serialize, serialize o @graph pra string ao renderizar, injeta a tag script no html. é a forma mais limpa porque a fonte da verdade e o serializador são a mesma linguagem fortemente tipada.

#[derive(serde::Serialize)]
struct Article<'a> {
    #[serde(rename = "@type")] kind: &'a str,
    #[serde(rename = "@id")] id: String,
    headline: &'a str,
    author: IdRef<'a>,     // { "@id": "..." }
    publisher: IdRef<'a>,
    #[serde(rename = "datePublished")] published: &'a str,
}
// serde_json::to_string(&graph) vira o conteudo da <script type="application/ld+json">

rust compilado pra wasm no browser cai no mesmo poço da spa: se o wasm monta a página no cliente, o crawler não vê. a saída é renderizar no servidor (leptos, dioxus com ssr) ou pre-renderizar. wasm client-side não resolve descoberta por ia sozinho, o wasm é ótimo pra lógica do app, não pra entregar schema a crawler.

swift/ios, kotlin/android, nativo: o ponto que a maioria dos guias erra, não existe crawler lendo a UI de um app nativo, botar json-ld numa SwiftUI view ou Composable não gera visibilidade. o que torna conteúdo nativo descobrível por ia é do lado servidor: o backend expõe o mesmo @graph via web e via endpoint estruturado, o app consome esse backend (Codable, kotlinx.serialization), e o mesmo backend serve o json-ld pra crawlers e o /ask e /mcp pra agentes. o Google App Indexing (deep link e ViewAction no AndroidManifest) foi descontinuado, universal links e app links continuam úteis pra abrir o app a partir de uma URL mas isso é roteamento, não descoberta semântica. o SO (macos, ios, linux) é irrelevante pra camada de schema, que é sempre servidor + html ou endpoint.

plataformaonde o schema vivemecanismo
Next.js, Nuxt, SvelteKit, Astroserver component / ssr / ssgtag script no html inicial
Rails, Django, Laravel, Go, PHPtemplate no servidortag script no html inicial
SPA pura (Vite, CRA)index.html ou pre-renderhtml servido, não cliente
Rust servidor (axum, leptos ssr)serde no handlertag script no html inicial
Rust/wasm no clientepré-render ou ssrnunca só no cliente
Swift/iOS, Kotlin/Androidbackend que o app consomeendpoint, /ask e /mcp
desktop macos/linuxbackend que o app consomeendpoint, /ask e /mcp

validação contínua no CI/CD: schema quebra em silêncio, mudança de estrutura no CMS que corrompe um @id só aparece semanas depois quando as citações somem. adicione lint antes de cada deploy. Schema Markup Validator (validator.schema.org) valida sintaxe contra o vocabulário. Rich Results Test verifica elegibilidade dos rich results que ainda existem (Product, Review, Event). em ts, schema-dts pega erro em compile-time. trate o @graph como contrato, @id instável quebra o NLWeb tanto quanto quebraria um schema GraphQL.

FAQPage: o que morreu em 7 de maio de 2026

deprecação em três datas, todas num aviso pequeno no topo da doc de FAQ structured data do google, sem blog post nem explicação. 7 de maio de 2026: os rich results de FAQ pararam de aparecer. junho de 2026: removidos o filtro de aparição, o relatório no Search Console e o suporte no Rich Results Test. agosto de 2026: removido o suporte na API do Search Console.

o que continua: FAQPage segue tipo schema.org totalmente válido. o google depreciou a feature de exibição, não a marcação. a própria doc do google diz que dados estruturados não usados não causam problema, você pode deixar a marcação no lugar, e ela continua sendo rastreada por Bingbot, PerplexityBot e crawlers de RAG que indexam a web aberta. o schema nunca fez o trabalho, o conteúdo sempre fez. clear, direct, question-led content é um dos sinais mais fortes pra citação em ia, e FAQPage diz ao modelo de forma explícita “aqui está a pergunta, aqui está a resposta, esta fonte disse isso”. um estudo da Ahrefs de fevereiro de 2026 achou que só 38% das páginas citadas em AI Overviews ranqueiam no top 10 da busca tradicional, ou seja os sinais que ganham citação em ia não são os mesmos que ganham ranking clássico.

decisão prática: mantenha FAQPage onde pergunta e resposta são reais, úteis e visíveis na página. remova só se a marcação aponta pra conteúdo que não existe mais, ou se a seção era magra e foi posta só pra enfeite de SERP. arquive o histórico de aparição de FAQ antes do sunset.

NLWeb e MCP: o site vira endpoint conversacional

lançado pela microsoft no Build 2025, criado por R.V. Guha (a mesma pessoa por trás de RSS, RDF e Schema.org). early adopters: Shopify, Snowflake, O’Reilly, Tripadvisor, Eventbrite, Hearst. transforma um site em servidor MCP com dois endpoints.

/ask, REST que aceita query em linguagem natural e devolve json estruturado em schema.org. o usuário pergunta “qual o preço enterprise” e recebe um json com o dado real, não um link pra formulário de contato.

/mcp, endpoint agent-to-agent sobre o Model Context Protocol (o mesmo MCP da anthropic). torna o site descobrível e chamável por agentes como o Operator da OpenAI ou o Project Mariner do Google, sem raspar html.

os argumentos da api são iguais nos dois, a diferença é o formato do objeto de retorno (pra /mcp é objeto MCP). a implementação de referência é stateless, pra manter contexto entre chamadas você gerencia os prompts anteriores e reusa pra montar a query nova.

a implicação: json-ld limpo deixou de ser só comida de crawler, é o input que o NLWeb consome e o formato que devolve. um @graph bem construído com @id estável e entidades conectadas vira uma api conversacional sem reescrever o backend. os melhores resultados vêm de sites já estruturados como listas de itens (receitas, eventos, lugares, produtos). dado de junho 2026: cada endpoint NLWeb é nativamente também um ChatGPT app, suporta A2A além de MCP, e o stack de referência aceita PostgreSQL com pgvector como retriever nativo. repositório migrou pra nlweb-ai/NLWeb (python, com AskAgent, AgentFinder, DataFinder, ModelRouter), antes em github.com/microsoft/NLWeb.

POST https://exemplo.com/ask
Content-Type: application/json

{ "query": "quem escreveu sobre GEO neste site?", "site": "https://exemplo.com" }

por que isso é o vetor do nativo: pra um app swift ou kotlin sem versão web, expor um NLWeb /ask e /mcp sobre os dados é o que torna o conteúdo descobrível por agentes. é a ponte entre o grafo e o mundo agêntico.

robots.txt, user agents de ia, llms.txt

se você quer ser citado por ia, mantenha destravados os user agents de llm no robots.txt. bloquear deve ser decisão estratégica (ex conteúdo pago), sabendo que remove você de um canal de aquisição em crescimento.

User-agent: GPTBot
Allow: /
User-agent: OAI-SearchBot
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: Google-Extended
Allow: /
User-agent: CCBot
Allow: /

GPTBot e OAI-SearchBot são da OpenAI, PerplexityBot da Perplexity, ClaudeBot da Anthropic, Google-Extended controla uso em Gemini, CCBot é o CommonCrawl.

llms.txt, o veredito honesto: é real, é um índice em markdown de URLs importantes, não é mecanismo de bloqueio nem de ranking. o google não usa e não planeja usar (Gary Illyes e John Mueller já desinflaram o hype). alguns crawlers de llm e ferramentas de RAG têm suporte experimental, sem consenso de mercado. trate como camada opcional de discoverability, depois que json-ld, sitemaps e html semântico estiverem prontos, nunca como prioridade.

arquitetura de dados em quatro camadas (engine llm-ready)

camada 1, conteúdo e entidades, a fonte da verdade. modele o domínio como entidades e relações (Organization, Product, Feature, UseCase, Persona, Article, FAQ, Release). defina tipos, campos, enums, constraints e o significado de null e unknown com schema de validação. cada entidade com identificador estável único mapeável um a um com o @id. registre provenance, data de atualização, flags de confiança, idioma e público-alvo. é o grafo interno da aplicação, independente de schema.org.

camada 2, exposição pública, json-ld + html semântico. traduz o grafo interno pra schema.org. cada entidade persistente vira um nó com @id estável baseado no identificador interno, numa biblioteca compartilhada. cada template de página vira o @graph parcial. injete via ssr, ssg ou isr no html inicial. garanta a concordância tripla.

camada 3, retrieval e indexação pra llm, o RAG. crie índices vetoriais onde cada chunk carrega o texto, a referência ao @id da entidade, o tipo (Article, FAQ, Doc), data de atualização e idioma. use o mesmo vocabulário de identificadores em todo lugar (organizationId, productId, articleId) pro llm costurar resposta coerente entre json-ld, documentos internos e api. pra dados tabulares (preços, specs) mantenha tabelas e jsons com schema definido e exponha pro RAG e via tools.

camada 4, aplicação e engine, llm + tools + front-end. defina tools com schema de entrada e saída claro expondo operações sobre as entidades (buscarProductById, listarFaqsPorTema, obterResumoArticle). use o llm em structured output ou tool calling com validação de schema, reduz alucinação e acopla a resposta ao grafo. no front-end trate a resposta do llm como visão sobre o grafo, não verdade em si: sempre exiba a fonte, use os @id pra montar links, breadcrumbs e cards.

o princípio que amarra as quatro: o mesmo modelo de entidade vive no json-ld público, no backend, no contrato das tools e nos tipos do front-end. o front-end nunca inventa tipo, consome entidade tipada, componente de UI é função de entidade + contexto. e instrumente observabilidade: logue quando o llm cita uma entidade por @id e quais páginas usou, compare com referrals de AI Overviews e ChatGPT pra ver se mudança de schema reflete em mais citação.

sinais de qualidade que amplificam o schema

dois pontos com fonte: citar outras fontes dentro do seu conteúdo aumenta a chance de você ser citado por ia, sinaliza rigor epistêmico (método Quotation Addition do paper GEO). conteúdo com dados específicos e verificáveis, estatística com atribuição clara, recebe citação preferencial sobre afirmação vaga (Statistics Addition, achado de 30 a 40% mais visibilidade com estatística original).

síntese: lidere com resposta (TL;DR ou key takeaways no topo), parágrafos compactos, headings e listas descritivas, marque o que é afirmação versus opinião, mantenha um único H1 e hierarquia lógica de H2/H3, json-ld válido com datePublished/dateModified/author/breadcrumb, schema batendo com o conteúdo visível, fontes primárias citadas inline com seção de referências.

checklist consolidado

  1. um único bloco @graph por página.
  2. persistentes (Organization, WebSite, Person) declaradas uma vez, ancoradas na raiz com #, na camada global.
  3. entidades de página (WebPage, Article, Product, BreadcrumbList) ancoradas na URL + #fragmento, referenciando as persistentes por @id.
  4. ordem: persistentes antes das de página.
  5. sameAs pra Wikidata em Organization e Person.
  6. knowsAbout em Organization e Person com os tópicos de autoridade reais.
  7. mentions pra entidades secundárias importantes.
  8. SpeakableSpecification em Article e WebPage, cssSelector do resumo e dos H2.
  9. Dataset quando há dados tabulares ou métricas, com license e temporalCoverage.
  10. DefinedTerm pra vocabulário proprietário sem entrada no Wikidata.
  11. dateModified real e atualizado a cada edição.
  12. json-ld no html inicial via ssr/ssg/isr, nunca via useEffect. em nativo, via endpoint.
  13. tipagem do schema na linguagem do backend (schema-dts no ts, serde no rust, Pydantic no python).
  14. concordância tripla: texto visível, html semântico e json-ld dizendo a mesma coisa.
  15. semantic html em paridade: article, section, nav, aside, headings na hierarquia certa.
  16. GPTBot, OAI-SearchBot, PerplexityBot, ClaudeBot, Google-Extended, CCBot destravados no robots.txt.
  17. validado no Schema Markup Validator e Rich Results Test, com lint no CI/CD.
  18. NLWeb /ask e /mcp como próximo passo, depois do grafo estável. vetor obrigatório pra app nativo sem versão web.
  19. llms.txt como reforço secundário, por último.
  20. web/wasm client-side e spa: pré-render ou ssr, nunca confiar no cliente pra entregar schema a crawler.

ferramentas

validação: Schema Markup Validator (validator.schema.org, api pra CI), Rich Results Test (google), schema-dts (npmjs.com/package/schema-dts, tipos ts do google oss), Google Search Console (com filtro de AI Overviews). geração: next-seo (metadados e componentes de schema pra next.js), NLWeb reference implementation (github.com/microsoft/NLWeb, repo atual nlweb-ai/NLWeb). monitoramento de visibilidade em ia (categoria emergente, validar antes de adotar): share of citation e share of voice em AI Overviews, referrals de chat.openai.com e perplexity.ai comparando antes e depois de mudanças de schema.

bibliografia (eixos)

papers: Aggarwal et al, GEO: Generative Engine Optimization, KDD 2024 (doi 10.1145/3637528.3671900, preprint arxiv 2311.09735); Kumar et al, AI Answer Engine Citation Behavior, an Empirical Analysis of the GEO-16 Framework, arxiv 2509.10762 (set 2025, fonte do “metadata e frescor, html semântico, dados estruturados”, odds ratio 4,2, 78% citação cross-engine); Chen et al, Generative Engine Optimization: How to Dominate AI Search, arxiv 2509.08919; GEO-SFE: Structural Feature Engineering for GEO, arxiv 2603.29979 (mar 2026).

schema e google: Google Search Central, Mark Up FAQs with Structured Data (com o aviso de deprecação de 7 mai 2026); Introdução a dados estruturados; Schema.org versão atual e SpeakableSpecification e Statement; W3C JSON-LD 1.1 Best Practices (github.com/w3c/json-ld-bp).

FAQPage deprecation: Search Engine Land (Google to no longer support FAQ rich results, mai 2026); Search Engine Journal (Google Drops FAQ Rich Results From Search); Elementera AI.

NLWeb e web agêntica: Microsoft Source (Introducing NLWeb, 2025); nlweb-ai/NLWeb; NLWeb.ai docs; InfoWorld (NLWeb: Tapping MCP for natural language web search).

schema e llm: Search Engine Roundtable (Schema Helps Microsoft’s LLMs, citação de Fabrice Canel no SMX Munich); Search Engine Land (How schema markup fits into AI search, without the hype); Search Engine Journal (Structured Data and Ranking, John Mueller, sem boost de ranking).

implementação: google/schema-dts; Google Open Source Blog (schema-dts turns 1.0); Enodo (Modern JSON-LD implementation in 2025); Mike Bifulco (Structured data JSON-LD for Next.js sites).

llms.txt: Limy.ai (LLMs.txt in 2026, documenta que o google não usa).

seo e webassembly

conteúdo de terceiro, não é material meu. fonte: artigo “The Future of SEO with WebAssembly” da gtechme (gtechme.com/insights/webassembly-seo-future-challenges), agência de desenvolvimento web nos eua. em inglês, originalmente com call-to-action de venda da gtechme, removido. fica aqui só a espinha técnica, por ser adjacente aos clusters de wasm e útil pra quem publica conteúdo em wasm.

tese central: wasm dá velocidade quase nativa no browser (edição de imagem, mapas 3d, analytics pesado, criptografia, sem round-trips de servidor), o que ajuda core web vitals e reduz bounce. mas ranqueamento depende de crawlers descobrirem, renderizarem e entenderem a página, e wasm não resolve crawlability por padrão.

o problema de opacidade: se conteúdo ou links importantes só aparecem depois que um script cliente roda, ou se o html entrega cascas vazias preenchidas só por um boot de wasm, o crawler pode ver conteúdo “fino”. se a informação só existe na memória depois que uma função wasm executa, o crawler pode nunca vê-la.

correção (rendering híbrido): entregar html renderizado no servidor ou estático pra páginas-chave, com texto, headings e links significativos no primeiro load, só então sobrepor wasm pro trabalho pesado. tratar js e wasm como complementares: js cuida da camada de ui e do glue (links e texto crawláveis), wasm cuida da parte intensiva. tratar hidratação e interatividade como progressive enhancement.

padrões que funcionam: pré-renderizar título, meta tags, canonical, structured data e conteúdo primário sem rodar scripts. code-split (carregar módulos wasm só nas rotas que precisam, reduz payload inicial e melhora core web vitals). expor dados crawláveis (se wasm gera texto/detalhes importantes, também renderizar no servidor ou embutir no html). instrumentar tracking na fronteira js, porque algumas libs de analytics não capturam interações dentro do módulo wasm.

frameworks: usar server components ou ssr pra páginas de conteúdo e hidratar só onde necessário (react, vue, svelte com island architecture). o princípio é comum: entregar html indexável, depois acoplar interatividade.

medição: benchmark antes e depois, acompanhar lcp, inp e cls com dados de campo, e cruzar com análise de logs pra confirmar frequência de crawl e latência de render.

contexto declarado no artigo (não verificado de forma independente): menção a WebAssembly 3.0 com garbage collection e multi-threading padronizados, e a afirmação de que googlebot executa wasm mas com limites de recursos, podendo atrasar ou completar parcialmente o render, o que reforça manter uma versão estática do conteúdo pra indexação confiável. o artigo cita tarefas em wasm “até 600% mais rápidas que scripts tradicionais”, número de marketing da própria agência, registrar com a ressalva.

a ponte com o resto: isso é exatamente o que [[geo-schema-json-ld]] resolve do lado do schema. wasm client-side cai no mesmo poço da spa pura, o crawler não vê. a saída é ssr/pré-render mais json-ld no html inicial.