Skip to content

Crescimento/Convite: link da sala não gera preview — robots.txt bloqueia o unfurl de /room/ e o card herda a OG genérica da home (robots.ts:13, room/[id]/page.tsx:9-14) #118

Open

Description

@caioross

Contexto

O convite de sala é o loop de aquisição nº1 do CodeRacer: sem login, a única forma de alguém chegar
ao produto por indicação é receber um /room/<code> de um amigo. A frota já construiu as duas pontas
do gesto — copyLink() em src/components/Lobby.tsx:60-65 e o chip "copiar link" em
src/components/RoomView.tsx:265-269 — e a chegada é ótima (o NameGate em
src/components/RoomView.tsx:178-215 já diz "você foi convidado", mostra o código e pré-preenche o
nick do localStorage). O elo fraco é o meio do caminho: como esse link aparece no chat.

Dois defeitos independentes, ambos conferidos na produção (2026-08-01):

1. O robots.txt bloqueia o próprio unfurl. src/app/robots.ts:13 publica Disallow: /room/.
Vários unfurlers respeitam robots.txt antes de buscar a página (Slackbot e Twitterbot são os casos
documentados; Discord e WhatsApp normalmente não). O comentário em src/app/robots.ts:4-6 justifica o
bloqueio por indexação — mas indexação já está impedida pelo robots: { index: false, follow: false }
de src/app/room/[id]/page.tsx:12, que é o mecanismo certo para isso. O Disallow não acrescenta
proteção de índice e custa o preview do convite nos clientes que o respeitam.

2. Quando o unfurl acontece, o card não fala da sala. A rota define title/description próprios
(src/app/room/[id]/page.tsx:9-14) mas nenhum openGraph, então herda a imagem genérica da home.
O convite vira mais um card institucional do CodeRacer em vez de "sala ABC123, entra aí".

Ordem sugerida: puxar depois da #117. Enquanto a origem pública estiver errada, o og:image
aponta para um host 503 e nenhum card renderiza — o efeito desta issue não seria observável.
Não é bloqueio de código: os diffs não se sobrepõem.

Escopo

  • src/app/robots.ts — parar de bloquear o fetch de /room/, mantendo as salas fora do índice pela
    meta noindex que já existe na rota. Atualizar o comentário para registrar a distinção entre
    "não indexar" e "não deixar buscar". /harness/ continua bloqueado.
  • Imagem OG por sala, derivada exclusivamente do código presente na URL — sem nenhuma leitura de
    banco: código em destaque, marca, e uma chamada curta ("entre na corrida"). Espelhar o shape de
    src/app/opengraph-image.tsx em vez de inventar um novo.
  • openGraph/twitter na metadata da rota da sala, para o card usar o título específico que ela já
    monta (Sala <CODE> — entre na corrida) em vez do título do layout raiz.

Restrição de segurança (deliberada): a imagem não pode consultar rooms nem qualquer estado —
nada de "3 jogadores esperando", nome do líder ou linguagem. Um endpoint público que devolve estado de
sala a partir do código seria um vetor de enumeração novo, exatamente o problema que a #103 (policy
using(true), sala privada enumerável) está tratando, e um alvo de abuso sem custo como o da #104
(POST /api/rooms sem rate limit). Tudo que a imagem mostra já é conhecido por quem tem o link.

Acceptance criteria (verificáveis)

  • GET /robots.txt em produção não contém Disallow: /room/; /harness/ segue bloqueado.
  • GET /room/<code> continua servindo <meta name="robots" content="noindex, nofollow"> (ou
    equivalente) — a mudança do robots.txt não pode tornar salas indexáveis. Cole o HTML no PR.
  • GET /room/<code> publica og:image próprio (não o da home) e og:title com o código da sala.
  • A imagem OG da sala responde 200 image/png com 1200×630 e mostra o código pedido; dois códigos
    diferentes produzem imagens diferentes. Cole as duas URLs/screenshots no PR.
  • A geração da imagem não faz nenhuma chamada a Supabase nem lê rooms — verificável por leitura do
    diff; declare isso explicitamente no PR.
  • Código inválido/estranho na URL não quebra a rota nem injeta conteúdo arbitrário na imagem —
    aplique o mesmo saneamento que a rota já usa (params.id.toUpperCase().slice(0, 6),
    src/app/room/[id]/page.tsx:8).
  • Gate: pnpm typecheck · pnpm build · pnpm test verdes.

Dica de abordagem

opengraph-image.tsx é uma convenção de arquivo do App Router e funciona dentro de app/room/[id]/,
recebendo os mesmos params da página — é por aí, sem rota de API nova. Reaproveite as cores de
src/lib/site.ts (themeColor, accentColor) para o card ficar coerente com o da home. Sobre o
robots.txt: a mudança é de uma linha, mas escreva no PR por que noindex na rota já cobre a
preocupação original de src/app/robots.ts:4-6 — é o ponto que um revisor vai querer ver defendido.

Activity

  1. added
    P2Prioridade normal
    area:uiInterface, design system, animação, game feel
    area:infraCI/CD, build, tooling, deploy, deps
    on Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Prioridade normalarea:infraCI/CD, build, tooling, deploy, depsarea:uiInterface, design system, animação, game feel

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions