Frontends com Vibecoding · Capítulo 14 de 33 · 28 min
Publicar conteúdo encontrável em vários idiomas
Você decide como cada página é montada, preenche metadados e a cápsula de resposta, e tira todo texto do código para um catálogo por idioma.
Este capítulo faz parte do curso gratuito Frontends com Vibecoding.
Uma página só existe para o buscador e para o assistente de IA quando o servidor entrega o texto pronto, e cabeçalho e corpo dizem a mesma coisa. Indexar é isso: o robô do Google ou do ChatGPT lê o texto da página e o guarda numa lista de onde tira as respostas.
Quem decide a tecnologia do site e quer ser citado escolhe a montagem de cada página, preenche os quatro metadados e escreve a frase que o assistente copia.
Três caminhos entregam o conteúdo pronto para quem rastreia, e você escolhe página por página. A geração estática grava o arquivo pronto antes de alguém pedir, e serve o mesmo texto a todos. É o certo para blog e ficha de produto que muda pouco.
A montagem no servidor refaz a página a cada pedido, o certo quando preço ou estoque muda o dia inteiro. O oposto disso é a página montada só no navegador, a tal SPA. Nela o servidor manda um arquivo quase vazio e o texto só aparece depois, quando o robô já foi embora.
Site de conteúdo sem área logada sai mais leve no Astro, que manda quase zero JavaScript ao navegador. Site novo com área logada começa no Next.js, o conjunto de ferramentas prontas que monta o site e já entrega o texto pelo servidor.
O teste que resolve a dúvida em dez segundos: abra a página, desligue o JavaScript nas configurações do navegador e recarregue. Se o texto sumiu da tela, ele também some do índice do Google e da resposta do assistente.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Buscador e assistente só conseguem citar um endereço. Aba, filtro e página de resultado que vivem só na memória do navegador não têm endereço, e o link copiado volta para a tela inicial. Guarde esse estado na URL, com o nuqs em React, e cada combinação de filtro vira uma página citável.
Preparar a página para ser encontrada, o que se chama SEO técnico, esbarra na rolagem infinita. O rastreador não rola, o leitor de tela não alcança o rodapé e a pessoa não consegue voltar ao item 40. Paginação numerada, com endereço próprio para cada página, resolve os três de uma vez.
A Speculation Rules API, a lista, no HTML, dos endereços que o navegador busca antes do clique, pré-carrega a ficha do produto enquanto a pessoa lê a lista. O manual a recomenda para menus e paginação. Cada endereço listado gasta dado do celular de quem talvez nunca clique, por isso liste só o destino mais provável.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
<!-- no head da página de lista: pré-carrega a ficha mais provável -->
<script type="speculationrules">
{
"prerender": [{
"where": { "href_matches": "/quartos/*" },
"eagerness": "moderate"
}]
}
</script>No arquivo da rota fica a função generateMetadata, o código que preenche título, descrição e endereço oficial da página. Ela devolve um objeto que o Next.js transforma nas linhas do cabeçalho, e a descrição fica entre 150 e 160 caracteres.
Se a rota responde em /blog/artigo e o endereço preferido declarado no rel=canonical diz /blog/artigo/, com barra no fim, o Google trata as duas como cópia. A página sai do índice sem aviso, por isso o endereço declarado precisa casar barra por barra com o que o site serve.
O JSON-LD, um bloco de texto dentro da página, no vocabulário schema.org, dizendo o que ela é, descreve autor, data e organização. Preencha só o que a página mostra de verdade: marcar algo que não aparece no texto visível é motivo declarado de penalidade nas diretrizes do Google.
Por hora investida, o que rende mais é a cápsula de resposta, a frase curta que responde direto à pergunta do título, logo no início da seção. Abra cada seção com a pergunta real como título e responda na primeira frase, em texto que se sustente sozinho fora da página.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Antes de publicar uma página nova, desligue o JavaScript do navegador e recarregue. Se o texto sumir da tela, ele some do índice e da resposta do assistente; troque a montagem antes de seguir adiante.
Depois escreva o título como a pergunta que a pessoa faz e responda na primeira linha, com número e condição: R$ 420 o casal, com café da manhã. É essa frase que o assistente copia, e é por ela que a pousada aparece na resposta em vez do concorrente.
Deu certo quando o texto continua na tela com o JavaScript desligado e a primeira linha de cada seção responde sozinha, fora da página.
Publicar o mesmo site em vários idiomas sem duplicar o código
A página já é encontrável e citável em um idioma, e o texto preso no código impede que ela exista nos outros sem reescrita.
Levar o produto para outro idioma é dois trabalhos: o de engenharia, feito uma vez, e o de conteúdo, repetido a cada mercado. O custo do segundo quase iguala o do primeiro, porque cada tela precisa ser reaberta à mão.
Preparar o site para receber outros idiomas tem nome, internacionalização, e é o trabalho de engenharia. Quem decide expandir estima o prazo pelo catálogo de chaves, pela formatação entregue ao navegador e pelo critério entre quatro bibliotecas.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Quem mistura os dois trabalhos cola lógica de tradução dentro do componente, a peça de tela que se repete, e a conta aparece no segundo idioma. A saída é uma indireção simples: cada texto recebe um identificador, a chave, e o produto pede o texto por essa chave.
A tradução vive num catálogo por idioma, um pt-BR.json e um en-US.json com as mesmas chaves preenchidas, e acrescentar um idioma vira entregar mais um arquivo.
Vale uma regra barata: nunca monte frase traduzida juntando pedaços. A ordem das palavras muda de idioma para idioma. Em alemão o verbo vai para o fim, em japonês o objeto vem antes do verbo, em árabe a frase corre ao contrário. O operador de soma congela a ordem do português dentro do código, onde nenhuma tradução consegue consertá-la.
Cada chave leva a frase inteira com marcador de variável, como t("inbox", { total }), e o catálogo guarda "Você tem {total} mensagens". Quando a frase varia por quantidade, a variação entra nela mesma, no formato ICU: "{total, plural, one {# mensagem} other {# mensagens}}". O tradutor passa a controlar a frase toda, incluindo a posição da variável.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Data, número, moeda e plural têm formatação nativa em todos os navegadores relevantes, pela API Intl, a interface que o navegador expõe para formatar valores por idioma. Monte o preço à mão e você erra separador, posição do símbolo e casa decimal. O real sai R$ 1.234,56, o dólar inverte ponto e vírgula, e o iene não tem casa decimal.
O Intl.PluralRules resolve o plural: o árabe tem seis categorias, o russo quatro, o polonês três, e o navegador informa qual categoria uma quantidade ativa. A direção de leitura também sai de graça, pelo CSS. Margem e alinhamento escritos em início e fim da linha, como margin-inline-start e text-align: start, espelham o layout sozinhos em árabe e hebraico.
A biblioteca junta catálogo, roteamento por idioma e formatação, e o critério de escolha é onde a mensagem é resolvida. O Paraglide JS e o Lingui resolvem no build, a etapa que gera os arquivos do site antes de publicar. Cada chave vira uma função, o navegador recebe só o idioma pedido e nada sobra para carregar.
O next-intl segue como padrão para o Next.js, porque integra com o endereço por prefixo de idioma e funciona no servidor. O react-i18next fica para a base antiga que já o usa, porque migrar catálogo que funciona sai mais caro que o ganho.
Escreva o nome escolhido dentro do pedido ao agente, porque pedido sem nome de biblioteca volta com uma opção que ninguém no time conhece. Para o next-intl, instale, crie os arquivos de mensagem de cada idioma com as mesmas chaves, e crie o arquivo que devolve as mensagens do idioma ativo.
Mova as páginas para a pasta do idioma e acrescente o redirecionamento da raiz para o idioma padrão, para que quem chega sem escolher caia no português.
Quatro bibliotecas, um critério: onde a mensagem é resolvida
| Biblioteca | Quando a mensagem é resolvida | Para qual stack | Escolha quando |
|---|---|---|---|
| next-intl | em tempo de execução, no servidor ou no navegador | Next.js com App Router | o projeto é Next.js e usa componente de servidor |
| Paraglide JS | no build, cada chave vira uma função | TanStack Start, SvelteKit e Astro, com suporte oficial desde janeiro de 2026 | o site roda na borda de rede e cada kB conta |
| Lingui | no build, catálogo compilado | React e JavaScript puro, com formato ICU | a equipe já escreve mensagens em ICU e quer o ganho de build fora do Paraglide |
| react-i18next | em tempo de execução, no navegador | base React legada que já o usa | migrar o catálogo que funciona sai mais caro que o ganho |
Critério da edição de setembro de 2026 do manual: Paraglide e Lingui compilam no build, com overhead zero em borda de rede; react-i18next segue para bases legadas.
Antes de publicar a segunda versão, abra a mesma tela nos dois endereços de idioma e confira se preço, data e plural mudam de formato sozinhos. Se não mudarem, a chamada ainda está escrita à mão, e o texto solto precisa virar chave.
O sinal mais barato de que falta chave é o preço. Formatado à mão, um aluguel de R$ 2.500,00 sai igual em espanhol, e a frase montada por soma erra o plural.
Deu certo quando você troca o idioma no endereço e a mesma tela mostra moeda, data e plural no formato do país, sem ninguém tocar no código.
Guia prático: o template de página única chega sem metadados, e o vídeo pode virar texto encontrável
Todos os 51 templates de site medidos em 07/10/2026 são feitos com Vite, e quase todos montam a página no navegador. O que eles trazem no cabeçalho mostra o trabalho que sobra para quem publica:
| Item | Templates |
|---|---|
| Marcados como inglês (lang="en") | 35 de 51 |
| Sem meta description | 33 de 51 |
| Sem Open Graph, a capa do link compartilhado | 42 de 51 |
| Sem canonical e sem JSON-LD | 51 de 51 |
Há ainda o endereço que quebra. Trinta templates usam BrowserRouter, o roteador que cria endereços limpos como /cardapio. Num host estático sem regra de reescrita, quem abre esse link direto ou recarrega a página recebe erro 404, e o arquivo de instruções do template promete que o site sobe "sem configuração extra". No Netlify, a regra é uma linha no arquivo _redirects que entrega o index.html com status 200; no Vercel, uma reescrita no vercel.json.
O vídeo é a outra metade. A transcrição com tempo por palavra, que a edição já produz, vira três ativos encontráveis: os capítulos na descrição do YouTube, com o primeiro em 00:00, pelo menos três capítulos e cada um com 10 segundos ou mais; a transcrição publicada na página do vídeo, em HTML; e os títulos dos capítulos como subtítulos dessa página. O que estava só na fala passa a ser texto que buscador e assistente leem.
Prepare este site de página única para ser encontrado. Não mude o visual.
1. index.html: lang="pt-BR", title de até 60 caracteres, meta description
de até 155, Open Graph com imagem de 1200x630, canonical e JSON-LD do
tipo [LocalBusiness | ProfessionalService | Restaurant] com os dados de
[arquivo de configuração].
2. Cada rota do roteador ganha título e descrição próprios.
3. Crie a regra de reescrita do host [Netlify | Vercel] para que abrir
[/rota-interna] direto e recarregar não deem 404. Teste as duas coisas.
4. Página do vídeo [nome]: a partir da transcrição com tempo por palavra,
gere os capítulos para a descrição (primeiro em 00:00, pelo menos três,
cada um com 10 s ou mais) e publique a transcrição em HTML, com os
títulos dos capítulos como h2.Do template mudo à página que buscador e assistente leem
Cinco passos para o dia em que você publica um template ou um vídeo novo.
Passo 1: Leia o cabeçalho que veio no template
Abra o index.html e confira idioma, título, descrição, Open Graph, canonical e JSON-LD. Templates trazem título de outro tema e idioma errado com frequência.
Deu certo quando: Você tem a lista do que falta, item por item.
Erro comum: Confiar no título que aparece na aba sem ler o que o compartilhamento mostra.
Passo 2: Preencha os metadados com dados reais
Use o pedido do bloco de código. O JSON-LD leva nome, endereço, telefone e horário do negócio, os mesmos que estão na página e no perfil de empresa no Google.
Deu certo quando: O link colado no WhatsApp mostra título, descrição e imagem certos.
Erro comum: Deixar a imagem de compartilhamento padrão do template, com o nome de outra empresa.
Passo 3: Teste o link profundo e a recarga
Abra uma rota interna direto numa aba anônima e recarregue a página nela. Se der 404, falta a regra de reescrita do host.
Deu certo quando: Toda rota abre direto e sobrevive à recarga.
Erro comum: Testar só navegando a partir da página inicial, onde o roteador esconde o problema.
Passo 4: Transforme a transcrição em capítulos
A partir da transcrição com tempo, peça os capítulos no formato da descrição do YouTube. Confira as três regras: primeiro em 00:00, pelo menos três, cada um com 10 segundos ou mais.
Deu certo quando: Os capítulos aparecem na barra do vídeo depois de salvar a descrição.
Erro comum: Começar o primeiro capítulo em 00:05 e o YouTube ignorar todos.
Passo 5: Publique a transcrição como texto da página
Na página do vídeo, a transcrição revisada entra em HTML, com os capítulos como subtítulos. Desligue o JavaScript e recarregue para conferir que o texto continua lá.
Deu certo quando: A transcrição aparece com o JavaScript desligado.
Erro comum: Publicar a transcrição só dentro do player ou como arquivo para baixar.
No fim você tem: Um site de página única com idioma, metadados e rotas que funcionam direto, e vídeos cujo conteúdo falado virou capítulo e texto encontrável.
Guia prático: dizer a cada robô o que ele pode ler e quando a página mudou
A aula ensinou a entregar o texto pronto e a descrever a página. Falta a conversa com quem rastreia: cada empresa de IA manda robôs diferentes para buscar, para atender um pedido no chat e para treinar modelo, e cada um obedece a uma linha própria do robots.txt (o arquivo na raiz que diz o que cada robô pode ler). Você sai deste guia separando busca de treino, com data verdadeira no sitemap e um llms.txt gerado do mesmo catálogo.
Funções, casos de uso e aplicações
Funções
Os recursos que conversam com buscadores e assistentes
| Função ou recurso | O que faz | Quando usar | Referência |
|---|---|---|---|
| Regra por robô no robots.txt | Dá uma regra a cada robô pelo nome: OAI-SearchBot e Claude-SearchBot buscam, GPTBot e ClaudeBot coletam para treino | Quando a página deve aparecer na resposta do assistente sem alimentar treino de modelo | Páginas de robôs da OpenAI e da Anthropic (esta de 07/04/2026) |
| Visita pedida no chat (ChatGPT-User, Claude-User) | Abre a página quando uma pessoa pede ao assistente; não decide entrada na busca | Liberar nas páginas públicas; a OpenAI avisa que o robots.txt pode não valer para essa visita | Página de robôs da OpenAI |
| Google-Extended | Marca do robots.txt que decide se o conteúdo rastreado pelo Google treina e alimenta o Gemini; não é um robô à parte | Quando quer ficar na busca do Google e sair do treino; não muda posição na busca | Google, página atualizada em 14/07/2026 |
| lastmod no sitemap | Informa a data da última mudança relevante de cada endereço | Sempre, com a data real do conteúdo; ano novo no rodapé não conta como mudança | Google, página atualizada em 08/07/2026 |
| priority e changefreq | Campos antigos do sitemap | Pode omitir: o Google ignora os dois | Google, página atualizada em 08/07/2026 |
| llms.txt | Arquivo em Markdown na raiz: título, resumo em citação e listas de links que o assistente lê primeiro | Site com muito conteúdo; a seção Optional guarda o que pode ser pulado | llmstxt.org, versão 2 de 10/08/2026 |
| Página em .md | O mesmo conteúdo em Markdown limpo, anunciado por link rel="alternate" type="text/markdown" | Preço, dúvidas frequentes e documentação que agentes consultam muito | llmstxt.org |
Robô de busca e robô de treino têm nomes diferentes de propósito: bloquear um não bloqueia o outro.
Casos de uso
Coordenadora de marketing de uma escola de cursos livres online em Curitiba
Educação
Dor
Quer que as páginas de curso apareçam quando alguém pergunta ao ChatGPT ou ao Claude por um curso de Excel, mas não quer o conteúdo das aulas pagas usado em treino de modelo.
Solução
Pediu ao agente um robots.ts com três grupos: robôs de busca liberados nas páginas públicas, robôs de treino fora do site inteiro e a área do aluno fechada para todos. Conferiu o arquivo servido em /robots.txt antes de publicar.
Resultado
O que observar: nos registros de acesso do servidor, depois de cerca de 24 horas, visitas do OAI-SearchBot às páginas de curso e nenhuma do GPTBot. Releia em duas semanas.
Custo apurado: Sem custo de ferramenta; meia hora de revisão.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Sócio de uma agência de marketing digital em Recife com blog de 300 artigos
Marketing digital
Dor
O sitemap carimbava em todos os endereços a hora do último deploy, e artigos revisados não eram relidos pelo buscador antes dos intocados.
Solução
Trocou a data do sitemap pela data de revisão gravada em cada artigo, omitiu priority e changefreq e passou a gerar o llms.txt a partir da mesma lista do sitemap.
Resultado
O que observar: no Search Console, relatório de Sitemaps e inspeção de URL, se os artigos revisados são rastreados antes dos antigos nas quatro semanas seguintes.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Na prática
Neste portal, o robots.txt sai de uma rota de servidor em src/app/robots.txt/route.ts, no lugar do objeto tipado do Next.js, porque precisa servir uma linha de preferência de uso de IA que o tipo não aceita. A lista de robôs separa busca, visita pedida e treino pelo nome. O sitemap em src/app/sitemap.ts lê a data de cada rota de src/generated/route-lastmod.json, um manifesto com a data do último commit da página; rota sem data sai sem lastmod, em vez de levar a hora do build. Na esteira, o passo "llms.txt em paridade com o sitemap" regenera o llms.txt a partir dos mesmos buckets e reprova endereço inexistente ou redirecionado.
// Crawlers IA (LLM training + realtime assistants)
const AI_BOTS = [
"GPTBot",
"ChatGPT-User",
"OAI-SearchBot",
"Googlebot",
"Google-Extended",
// ...
"ClaudeBot",
"Claude-User",
"Claude-SearchBot",
"PerplexityBot",
// ...
];
// Regra Allow mais específica (mais longa) vence o Disallow
// genérico (RFC 9309).
const API_ALLOW_EXCEPTIONS = [
"/api/mcp",
"/api/mcp/",
"/api/oauth/register",
"/api/oauth/token",
];// app/robots.ts — projeto de campanha em Next.js (exemplo)
import type { MetadataRoute } from "next";
const SITE = "https://campanha.exemplo.com.br";
const FECHADO = ["/obrigado", "/api/", "/area-do-aluno/"];
export default function robots(): MetadataRoute.Robots {
return {
rules: [
// Busca dos assistentes: lê as páginas públicas
{ userAgent: ["OAI-SearchBot", "Claude-SearchBot", "PerplexityBot"], allow: "/", disallow: FECHADO },
// Visita pedida por uma pessoa no chat
{ userAgent: ["ChatGPT-User", "Claude-User"], allow: "/", disallow: FECHADO },
// Treino de modelo: fora do site inteiro
{ userAgent: ["GPTBot", "ClaudeBot", "Google-Extended"], disallow: "/" },
// Demais robôs, inclusive o Googlebot da busca
{ userAgent: "*", allow: "/", disallow: FECHADO },
],
sitemap: SITE + "/sitemap.xml",
};
}Do robots.txt genérico à conversa com cada robô
Passo 1: A finalidade de cada robô decide a regra
Escreva três linhas: quem pode buscar, quem pode abrir a pedido de uma pessoa e quem pode treinar. A mesma empresa aparece nas três com nomes diferentes.
Deu certo quando: Cada robô da lista tem uma decisão e um motivo.
Passo 2: Gere o robots.txt pelo código e leia o servido
Abra /robots.txt no navegador depois do build. Vale o arquivo servido, que pode diferir do que está no editor.
Erro comum: Bloquear /api/ inteiro e esquecer o endpoint público que o llms.txt anuncia.
Passo 3: Troque a data do sitemap pela data do conteúdo
Use a data de revisão gravada na página ou a do último commit do arquivo dela. Sem data conhecida, deixe o campo de fora.
Deu certo quando: Duas páginas que não mudaram mantêm a mesma data depois de um deploy novo.
Passo 4: Gere o llms.txt do mesmo catálogo
Uma fonte só para sitemap e llms.txt evita link morto no arquivo que o assistente lê primeiro. Ponha a conferência na esteira.
Passo 5: Depois de 24 horas, leia os registros de acesso
Filtre o log por nome de robô. A OpenAI informa que mudanças para o robô de busca levam cerca de um dia para valer.
Deu certo quando: Robô de busca presente nas páginas liberadas e ausente nas fechadas.
No fim você tem: Buscadores e assistentes leem o que você quer mostrar, e a data no sitemap passa a indicar mudança real de conteúdo.
Armadilhas
Robots, sitemap e llms.txt: o que evitar e o que pedir
Evitar
Coluna a evitar
- Bloquear GPTBot achando que sai da busca do ChatGPT: quem busca é o OAI-SearchBot
- Bloquear o robô por endereço IP, que pode impedir a leitura do próprio robots.txt
- lastmod com a hora do build em todos os endereços
- priority 1.0 em tudo, campo que o Google ignora
- llms.txt escrito à mão que envelhece com links mortos
Recomendado
Coluna recomendada
- Uma regra por finalidade: busca, visita pedida e treino
- Bloqueio pelo robots.txt, repetido em cada subdomínio
- lastmod com a data da última mudança relevante, ou nenhum
- Sitemap só com endereço e data
- llms.txt gerado da mesma lista do sitemap e conferido na esteira
Aplicar os recursos ao projeto
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
HTML semântico é a planta baixa da página: diz o que cada parte significa antes de dizer como aparece. Título, menu, corpo e botão ganham nome próprio, e navegador, busca e leitor de tela entendem o mesmo. Escolha o elemento pela tarefa que ele cumpre.
Você tem um manual de manutenção da sua oficina. Ponha o título em h1, o índice em nav e as instruções em main, as etiquetas nativas de cabeçalho, menu e corpo. Dê um id a cada seção, como revisao, e aponte cada item do índice para href='#revisao'.
Desligue o CSS e percorra a página com a tecla Tab. A ordem precisa continuar fazendo sentido e cada controle precisa dizer seu nome. Uma div pintada de botão obriga você a reprogramar o teclado inteiro; trocar essa div por um button resolve sozinho.
Fuse.js procura parecença de texto numa lista já carregada na memória. A busca aproximada perdoa parte dos erros de digitação e, em troca, às vezes traz item sem relação. Serve a catálogo local pequeno ou médio, quando dá para mandar os dados junto da página, sem serviço.
Embuta uma lista de capítulos com id, title e summary. Monte new Fuse(capitulos, { keys: ['title', 'summary'], includeScore: true, threshold: 0.3 }) e chame search(termo). Desenhe resultado.item e use o id como destino do link. O threshold é um ponto de partida e você ajusta com buscas reais dos seus clientes.
Digite uma palavra exata, uma com erro e outra sem nada a ver. Se os resultados saírem aleatórios, revise os campos e a tolerância. Termo vazio merece tratamento próprio. Para abrir o arquivo sem rede, embuta os dados e a biblioteca; puxar a lista com fetch recria a dependência.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
MiniSearch monta um índice de texto na memória, uma tabela que liga cada palavra aos documentos onde ela aparece. Com isso você busca em vários campos e ainda recupera trechos para mostrar. Cabe bem em manual e catálogo local que pedem busca por termo, prefixo e relevância.
Prepare documentos com id, title e text. Instancie new MiniSearch({ fields: ['title', 'text'], storeFields: ['title'] }) e rode addAll(documentos). Busque com search('contrat', { prefix: true }) para achar palavras que começam assim. Use o id devolvido para levar ao capítulo e o título guardado para escrever o rótulo do resultado na lista.
Confirme que cada documento tem id único e que mudar o conteúdo refaz o índice. Meça o tempo de montagem num celular simples quando houver muitos documentos. Índice em memória não guarda nada: para um manual de arquivo único, embuta os dados ou o índice pronto e teste sem internet.
Pagefind monta a busca depois que as páginas estáticas já existem. Ele lê o HTML pronto e gera arquivos de índice que o navegador consulta. O resultado dispensa um serviço de busca, mas ainda espera que os arquivos cheguem por um endereço web de verdade.
Gere o portal na pasta dist e rode pagefind --site dist com a ferramenta instalada. Marque a área principal com data-pagefind-body para indexar só o conteúdo, e não o menu. Publique também a pasta pagefind criada e chame new PagefindUI({ element: '#busca' }) depois de carregar o script e o estilo.
Procure uma frase que só existe numa página interna e veja se o resultado leva ao endereço certo. Índice velho? Gere de novo depois de mexer no conteúdo. Olhe os erros de módulo e de requisição. Não ter servidor de busca não quer dizer que abre por duplo clique.
Depois de encontrar, o leitor precisa interpretar
| Conteúdo | Preparar | Conferir |
|---|---|---|
| Expressão matemática | HTML, CSS e fontes | Leitura e significado |
| Mensagem traduzida | Chaves e dicionários | Plural e contexto |
| Valor formatado | Idioma e unidade | Sentido no público alvo |
KaTeX e i18next tratam da apresentação e interpretação do conteúdo; busca e indexação resolvem outra etapa da consulta.
KaTeX transforma notação matemática em fórmula legível na página. A conversão pode acontecer na hora de montar o material, poupando o celular do leitor de carregar um processador de fórmulas. Cabe em aula com equações fixas; calculadora que muda a fórmula pede o processamento no próprio navegador.
Na geração do manual, chame katex.renderToString('C = q p', { throwOnError: false, output: 'htmlAndMathml' }). Ponha o resultado no lugar da equação e leve junto os estilos e as fontes. Escreva também a explicação em prosa: o custo C é a quantidade q multiplicada pelo preço p.
Passe uma expressão inválida e veja como o erro aparece sem derrubar o resto da página. O MathML, a marcação de matemática, ajuda a tecnologia assistiva, mas confirme a compreensão no leitor de tela do seu público. Não libere comandos de confiança para texto que vem de fora; fonte remota também impede leitura offline.
i18next separa as mensagens da interface por idioma e resolve plural e valores encaixados no texto. Uma chave estável representa a frase, e cada catálogo guarda a tradução dela. A biblioteca organiza o material; ela não traduz termo da sua empresa nem escolhe formato de moeda e de data.
Inicie i18next com lng: 'pt-BR', fallbackLng: 'pt-BR' e resources: { 'pt-BR': { translation: { item_one: '{{count}} item', item_other: '{{count}} itens' } } }. Chame t('item', { count: 2 }) e receba o plural certo. Para preço, use Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }) e atualize o atributo lang no documento inteiro.
Teste singular, plural, chave que não existe e troca de idioma. Veja se os botões ainda cabem com tradução mais longa. Mantenha o tratamento seguro dos valores encaixados e evite inserir tradução como HTML. Para leitura offline, embuta os catálogos; carregador remoto continua dependendo da rede.
Seu caderno neste capítulo
Abrir o caderno completoSelecione um trecho do capítulo para destacar ou anotar. Nos vídeos e áudios, use Anotar este momento. No teclado, selecione com Shift e as setas e use Alt+Shift+D para destacar ou Alt+Shift+N para anotar.
Salvo neste navegador. Entre na sua conta para levar o caderno a outros aparelhos.
Entre na sua conta para compartilhar o que aprendeu e convidar alguém para estudar com você.
Conexões deste capítulo
Veja o que estudar antes e para onde seguir depois, explore os conceitos e compare abordagens em outros cursos. Sugestões marcadas como “sugerido pelo grafo” vêm dos assuntos em comum, não do índice do curso.
Estude antes
- CursoClaude Code CLI: Programação com IA
- Diagnostique em que etapa a busca perde a sua páginasugerido pelo grafoApresenta os conceitos “Robots.txt” e “Canonical”, usados em “Publicar conteúdo encontrável em vários idiomas”.
- Destrave o que impede o robô de ler o sitesugerido pelo grafoApresenta os conceitos “GPTBot” e “OAI-SearchBot”, usados em “Publicar conteúdo encontrável em vários idiomas”.
- Introdução ao Next.jssugerido pelo grafoApresenta o conceito “Next.js”, usado em “Publicar conteúdo encontrável em vários idiomas”.
Depois, siga para
- CursoPrompt Engineering para Executivossugerido pelo grafo7 capítulos de “Prompt Engineering para Executivos” usam conceitos apresentados em “Frontends com Vibecoding”.
- CursoLLM FinOps: o custo da IA para quem assina o orçamentosugerido pelo grafo3 capítulos de “LLM FinOps: o custo da IA para quem assina o orçamento” usam conceitos apresentados em “Frontends com Vibecoding”.
Conceitos deste capítulo
O mesmo assunto em outros cursos
- Autoridade Temática e SEO de EntidadesO trecho que a IA consegue usar sozinhoExaminar conexões de O trecho que a IA consegue usar sozinho
- Vibecoding para SEOO Manifesto Vibecoding: Programe sem ProgramarExaminar conexões de O Manifesto Vibecoding: Programe sem Programar
- RAG em produçãoQuando uma busca só não responde: decompor e rotearExaminar conexões de Quando uma busca só não responde: decompor e rotear
- MCP com Chrome: Automação com IADescobrir o que a IA não vê na página que você vêExaminar conexões de Descobrir o que a IA não vê na página que você vê
Voltar ao capítulo anterior: Construir formulários e estados de interação
Leve uma ideia para a prática
Escolha uma atividade no painel e volte a este curso quando quiser.
Atividades e evolução ficam reunidas no painel da sua conta.
Laboratórios ao vivo deste curso
Cada laboratório monta a biblioteca real dentro da aula, com controles para você mexer e o código do exemplo para copiar. O texto de reserva descreve a demonstração para quem lê sem JavaScript. O link abre o capítulo já no ponto do laboratório.
Base UI
Prenda o foco num diálogo sem escrever o comportamento
Abra a janela Agendar visita, percorra os campos com Tab, feche com Esc e acompanhe no painel onde o foco está e para onde ele volta.
Pacote
Abrir no capítuloConstruir componentes, usar o registro e publicar o catálogo@base-ui/reactLucide e Iconify
Mantenha uma família de ícones coerente e nomeie cada botão
Mude tamanho, traço e cor da barra, veja o símbolo do Iconify acompanhar o Lucide e rode a auditoria de nomes acessíveis.
Pacote
Abrir no capítuloProjetar uma linguagem de ícones e ilustraçãolucide-react, @iconify/reactMotion
Testar os três sinais que autorizam o terceiro degrau
Reproduza a entrada em sequência, aperte o botão com mola e arraste o cartão; ajuste rigidez e amortecimento e veja o que muda.
Pacote
Abrir no capítuloProjetar movimento, assinatura e narrativas por rolagemmotionVidstack
Ver o que separa um player de um vídeo cru
Dê o play, troque a velocidade e ligue a legenda; o painel ao lado mostra o estado que o player publica e que a etiqueta crua esconde.
Pacote
Abrir no capítuloProjetar movimento, assinatura e narrativas por rolagem@vidstack/reactcmdk
Achar um destino entre quarenta digitando três letras
Abra a paleta, digite fat e escolha um item só pelo teclado; o painel embaixo conta o que o filtro deixou passar e quanto tempo levou.
Pacote
Abrir no capítuloConstruir formulários e estados de interaçãocmdknumber-flow
Animar indicadores que mudam ao vivo com formato pt-BR
Veja três indicadores fictícios rolarem a cada troca e compare com o número em texto puro. Pause, reinicie e observe o separador de milhar.
Pacote
Abrir no capítuloProjetar gráficos e painéis pela decisão@number-flow/reactApache ECharts
Medir o custo de desenhar 200 mil pontos com o ECharts
Troque o tipo de gráfico e o volume de pontos, leia o tempo de desenho e alterne o eixo em zero. Mude o tema do site e veja as cores refazerem.
Pacote
Abrir no capítuloProjetar gráficos e painéis pela decisãoechartssharp e svgo
Escolher a variante certa da imagem e conferir o teto de 150 KB
Arraste a largura da tela simulada, troque a densidade entre 1x e 2x e veja qual arquivo o navegador escolhe, quanto ele pesa e se cabe no orçamento.
Pacote
Abrir no capítuloValidar desempenho, autenticação e segurançasharp, svgoReact Flow (xyflow)
Disparar um pedido e ver o orquestrador distribuir, conferir e responder
Alterne paralelo e sequencial, ligue e desligue a verificação e use a medição real; observe o tempo de parede em cada combinação.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robô@xyflow/reactGSAP, Web Workers e number-flow
Dividir mil tarefas entre trabalhadores reais e correr três ritmos de geração
Execute com um trabalhador, depois com quatro e oito, e compare o tempo; em seguida percorra a corrida e separe a espera inicial do ritmo.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robôgsap, @number-flow/reactThree.js com React Three Fiber, drei, Rapier e XR
Carregar o braço robótico, ver a física trabalhar e entrar na cena com o visor
Carregue a cena pelo botão, inicie o ciclo, mostre os ângulos das juntas, troque a câmera e a velocidade; com visor, entre em realidade virtual.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robôthree, @react-three/fiber, @react-three/drei, @react-three/rapier, @react-three/xrMotion
Ver quatro agentes em raias trocando mensagens e a revisão devolvendo um trecho
Reproduza os 60 s de modelo, percorra o tempo pelo controle e esconda as mensagens para comparar a leitura; repare no tempo de parede contra a soma.
Pacote
Abrir no capítuloEspecificar, medir e produzir as cenas da máquinamotionMediaRecorder, Canvas 2D e Long Animation Frames (plataforma)
Medir o quadro da cena e gravar seis segundos dela em vídeo
Suba as partículas, force um bloqueio de 300 ms e leia o medidor; depois grave seis segundos, veja o codec escolhido e baixe o arquivo.
Pacote
Abrir no capítuloEspecificar, medir e produzir as cenas da máquinasem pacotesigma.js, graphology com ForceAtlas2 e cosmos.gl
Ver o grafo real do curso e um grafo de milhares de nós se organizarem em aglomerados
Rode o layout no grafo real, passe o mouse pelos nós e busque uma entidade; troque para 20 mil nós e leia o medidor; depois carregue o modo massivo na placa de vídeo.
Pacote
Abrir no capítuloAnimar um grafo de conhecimento amplo em movimentosigma, graphology, graphology-layout-forceatlas2, graphology-generators, @cosmos.gl/graph
Capítulos vizinhos em Frontends com Vibecoding
- 12Construir profundidade e dirigir a montagem de vídeo
- 13Construir formulários e estados de interação
- 14Publicar conteúdo encontrável em vários idiomas
- 15Projetar gráficos e painéis pela decisão
- 16Dimensionar tabelas e organizar o cálculo das métricas