SEO técnico com Next.js: como implementei metadata, JSON-LD e sitemap dinâmico na Nexus G

Tecnologia··4 min de leitura
SEO técnico com Next.js: como implementei metadata, JSON-LD e sitemap dinâmico na Nexus G
Wendell Nunes Lima
Wendell Nunes Lima

@wendellnuneslima

No artigo anterior, contei os bastidores gerais da construção da Nexus G. Aqui vou entrar no código de verdade: como o App Router do Next.js resolve, na prática, os quatro pilares que fazem um perfil profissional ser rastreado, indexado e ranqueado pelo Google metadata dinâmica, dados estruturados, sitemap e performance.

O primeiro pilar é a Metadata API. Cada perfil da Nexus G é uma rota dinâmica, e cada uma precisa de title, description e Open Graph únicos usar o mesmo metadata genérico em todo perfil é um dos erros mais comuns que derruba ranqueamento por conteúdo duplicado. A solução do App Router é a função generateMetadata, que roda no servidor antes da página renderizar:

// app/[username]/page.tsx
export async function generateMetadata(
  { params }: { params: { username: string } }
): Promise<Metadata> {
  const profile = await getProfileByUsername(params.username);

  return {
    title: `${profile.name} - ${profile.role} | Nexus G`,
    description: profile.bio.slice(0, 155),
    openGraph: {
      title: profile.name,
      description: profile.bio.slice(0, 155),
      images: [profile.avatarUrl],
    },
    alternates: {
      canonical: `https://nexusg.site/${profile.username}`,
    },
  };
}

O dado vem direto do Supabase no momento da requisição, então qualquer atualização de bio ou avatar do usuário já reflete na próxima vez que o Google rastrear aquela página, sem precisar de novo deploy.

O segundo pilar são os dados estruturados, o JSON-LD. Metadata comum diz ao Google o que é a página; o JSON-LD diz o que aquilo significa. Um perfil profissional se beneficia do schema Person combinado com ProfilePage, o que ajuda o Google a entender que aquela URL representa uma pessoa real, com cargo, habilidades e link de portfólio exatamente o tipo de contexto que abre espaço pra rich snippet na busca:

function ProfileJsonLd({ profile }: { profile: Profile }) {
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'ProfilePage',
    mainEntity: {
      '@type': 'Person',
      name: profile.name,
      jobTitle: profile.role,
      description: profile.bio,
      url: `https://nexusg.site/${profile.username}`,
      knowsAbout: profile.skills,
    },
  };

  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
    />
  );
}

Esse componente é renderizado dentro da própria página de perfil, como Server Component o que nos leva ao terceiro ponto, talvez o mais crítico de todos: manter o conteúdo real dentro de Server Components, nunca atrás de useEffect num Client Component. A maioria dos crawlers, incluindo os de IA que hoje também indexam conteúdo, não executa JavaScript da mesma forma que um navegador comum executa. Se a bio, as habilidades e os artigos de um perfil só aparecerem depois de uma chamada de API disparada no client, o rastreador simplesmente não vê aquele conteúdo. Na Nexus G, todo dado que compõe o perfil público é buscado no servidor antes da resposta HTML ser montada, garantindo que o que o crawler recebe é idêntico ao que a pessoa vê na tela.

O quarto pilar é o sitemap dinâmico, resolvido pelo arquivo de convenção sitemap.ts na raiz do app:

// app/sitemap.ts
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const profiles = await getAllPublishedProfiles();
  const posts = await getAllPublishedPosts();

  const profileUrls = profiles.map((profile) => ({
    url: `https://nexusg.site/${profile.username}`,
    lastModified: profile.updatedAt,
    changeFrequency: 'weekly' as const,
    priority: 0.8,
  }));

  const postUrls = posts.map((post) => ({
    url: `https://nexusg.site/${post.profileUsername}/${post.slug}`,
    lastModified: post.updatedAt,
    changeFrequency: 'monthly' as const,
    priority: 0.6,
  }));

  return [...profileUrls, ...postUrls];
}

Essa função roda a cada requisição do sitemap, o que significa que todo novo conteúdo publicado um perfil recém-criado ou um artigo recém-lançado entra automaticamente na lista sem intervenção manual. O robots.ts complementa isso liberando explicitamente rotas de perfil e conteúdo público, enquanto bloqueia rotas administrativas e de painel, que não têm nenhum motivo pra aparecer indexadas.

Por fim, nada disso sustenta ranqueamento se a performance não acompanhar. Largest Contentful Paint, Interaction to Next Paint e Cumulative Layout Shift são hoje sinais diretos de ranqueamento, não só métrica de auditoria isolada. Na prática, isso significou usar next/image em toda imagem de perfil e capa, com prioridade explícita na imagem principal acima da dobra, usar next/font pra eliminar salto de layout por carregamento tardio de fonte, e revisar todo script de terceiro que entrava no perfil público cada um deles é candidato a atrasar interação e derrubar o INP se não for tratado com cuidado.

Juntos, esses quatro pilares metadata dinâmica, dados estruturados, renderização no servidor com sitemap automático, e performance tratada como requisito são o que transforma um perfil de simples página bonita em um ativo que o Google realmente encontra, entende e recomenda. É engenharia de SEO aplicada linha por linha, não configuração de plugin.

Comentários

Entre com Google para comentar.

Mais de Wendell Nunes Lima

Wendell Nunes Lima

Escrito por

Wendell Nunes Lima

Fundador e Desenvolvedor da Nexus G

Especialista em desenvolvimento de plataformas digitais e fundador da Nexus G, um ecossistema criado para fortalecer a autoridade profissional com conteúdo otimizado para SEO e páginas preparadas para ranquear no Google.