Desenvolvedores que usam o Next.js 13+ App Router frequentemente escrevem Server Components que buscam dados diretamente de um banco ou API. Ao usar o GitHub Copilot, o código gerado às vezes usa Client Components com hooks como useEffect ou useState, o que quebra a arquitetura server-first. Esse desencontro acontece porque os dados de treinamento do Copilot incluem muitos padrões React que assumem renderização no cliente. Este artigo explica como guiar o Copilot para produzir padrões corretos de Server Components para o App Router, incluindo busca de dados, tratamento de erros e composição de componentes.
Principais Conclusões: Padrões de Server Components com GitHub Copilot
- Convenção de nomenclatura de arquivos
page.tsxelayout.tsx: Arquivos dentro do diretórioapp/são Server Components por padrão. O Copilot respeita isso quando você abre o arquivo primeiro. - Diretiva
'use server'para Server Actions: Coloque-a no topo de um arquivo separado ou função inline para indicar ao Copilot que você quer lógica de mutação no servidor. - Comentário inline
// Server Component: Adicionar esse comentário no topo do arquivo reduz a chance de o Copilot sugeriruseStateouuseEffect.
Por que o Copilot Padroniza Client Components no Next.js
O GitHub Copilot aprende com bilhões de linhas de código público. A maioria dos exemplos de React no GitHub usa Client Components com hooks. Quando você começa a digitar em um arquivo .tsx, o Copilot não sabe automaticamente se o arquivo é um Server Component ou um Client Component. Sem dicas explícitas, ele sugere padrões como useEffect para buscar dados ou useState para gerenciar estado local. Esses padrões funcionam, mas quebram o modelo server-first do App Router, que prefere componentes assíncronos que buscam dados diretamente.
O App Router trata todo componente dentro do diretório app/ como um Server Component, a menos que o arquivo contenha a diretiva 'use client'. O Copilot pode detectar essa diretiva e ajustar suas sugestões de acordo. No entanto, ele não infere o contexto do diretório apenas pelo caminho do arquivo. Você deve fornecer sinais claros por meio da estrutura de arquivos, comentários ou das primeiras linhas que digitar.
Padrões para Guiar o Copilot para Server Components
Os padrões a seguir ajudam o Copilot a produzir código correto de Server Components. Aplique-os consistentemente em todo o seu projeto.
1. Comece com uma Assinatura de Função Assíncrona
Server Components no App Router são funções assíncronas. Quando você digita export default async function Page(), o Copilot reconhece imediatamente o contexto do servidor. Ele evitará sugerir hooks e, em vez disso, proporá chamadas await para busca de dados.
- Abra um novo arquivo no diretório
app/
Crie um arquivo comoapp/products/page.tsx. Não adicione'use client'no topo. - Digite a assinatura da função assíncrona
Escrevaexport default async function ProductsPage() {na primeira linha. Pressione Enter. - Aceite a sugestão de busca de dados
O Copilot provavelmente sugeriráconst products = await db.product.findMany()ou similar. Pressione Tab para aceitar. - Adicione o retorno JSX
Digitereturn (e deixe o Copilot sugerir um map sobre o array de produtos. Ele evitaráuseEffectporque a função é assíncrona.
2. Use Comentários Inline para Declarar Contexto
Um comentário simples no topo do arquivo informa ao Copilot o ambiente. Isso funciona mesmo se você ainda não digitou a assinatura da função.
- Adicione um comentário de contexto
Digite// Server Component — sem diretivana primeira linha.'use client' - Escreva o nome do componente
Digiteexport default function ProductList(). O Copilot agora evitaráuseStateeuseEffectporque o comentário sinaliza um contexto de servidor. - Busque dados diretamente
O Copilot sugeriráconst data = await fetchData()ou uma chamada ao banco. Aceite e envolva em JSX.
3. Defina Server Actions em Arquivos Separados
Server Actions são funções que executam no servidor, mas são chamadas a partir de Client Components. O Copilot frequentemente as confunde com rotas de API. Para obter sugestões corretas, defina as ações em um arquivo com a diretiva 'use server' no topo.
- Crie um arquivo de server actions
Crie um arquivo comoapp/actions.tsoulib/actions.ts. Adicione'use server'como primeira linha. - Escreva uma função assíncrona
Digiteexport async function createProduct(formData: FormData) {. O Copilot sugerirá lógica do lado do servidor, comoconst name = formData.get('name')e inserção no banco. - Importe a ação em um Client Component
Em um arquivo'use client', importe a ação e passe-a para um formulário. O Copilot sugerirácorretamente.
Erros Comuns Quando o Copilot Gera Server Components
Copilot Adiciona useEffect Dentro de um Server Component
Se você iniciar um arquivo sem uma assinatura assíncrona ou comentário de contexto, o Copilot pode sugerir useEffect para busca de dados. Isso causa um erro de build porque hooks não são permitidos em Server Components. Para corrigir, exclua o hook e substitua por uma chamada await dentro do corpo do componente. Em seguida, adicione a palavra-chave async à função.
Copilot Sugere 'use client' Desnecessariamente
Às vezes, o Copilot adiciona 'use client' no topo de um arquivo que apenas renderiza dados estáticos. Isso força o componente a se tornar um Client Component, perdendo os benefícios de desempenho da renderização no servidor. Remova a diretiva e certifique-se de que o componente não usa hooks ou APIs do navegador. Se você precisar de interatividade, mantenha a diretiva e mantenha o componente pequeno.
Código de Server Action Aparece Dentro de um Client Component
O Copilot pode sugerir escrever uma função de server action diretamente dentro de um arquivo 'use client'. Isso não funciona porque a função é executada no cliente. Mova a ação para um arquivo separado com 'use server' e importe-a. Em seguida, exclua a função inline do Client Component.
Server Component vs Client Component: Principais Diferenças
| Item | Server Component | Client Component |
|---|---|---|
| Padrão no App Router | Sim (arquivos em app/ sem 'use client') |
Não (requer diretiva 'use client') |
| Busca de dados | await direto dentro do componente assíncrono |
useEffect ou biblioteca de terceiros como React Query |
| Hooks permitidos | Não (useState, useEffect causam erros) |
Sim (todos os hooks React) |
| Dica necessária para o Copilot | Assinatura assíncrona ou comentário // Server Component |
Diretiva 'use client' na primeira linha |
| Impacto no tamanho do bundle | Nenhum JavaScript enviado ao cliente | JavaScript completo do componente enviado ao cliente |
Agora você pode escrever Server Components com o GitHub Copilot que seguem o padrão do App Router corretamente. Comece cada novo arquivo com uma assinatura de função assíncrona ou um comentário de contexto para evitar sugestões de hooks. Para Server Actions, sempre use um arquivo separado com a diretiva 'use server'. Como próximo passo, experimente o recurso de chat inline do Copilot para refatorar um Client Component existente em um Server Component digitando /fix e descrevendo a mudança.