Componentes de servidor vs. cliente
Por padrão tudo roda no servidor — "use client" é a exceção, não a regra.
No App Router, todo componente é Server Component por padrão. Ele roda no servidor, nunca manda seu próprio JavaScript pro navegador, e por isso pode fazer coisas que o navegador não devia fazer diretamente — ler um banco de dados, usar uma variável de ambiente secreta, chamar uma API interna.
// roda só no servidor — pode até acessar banco/arquivo direto
async function ListaDeProdutos() {
const produtos = await buscarProdutosNoBanco();
return (
<ul>
{produtos.map((p) => <li key={p.id}>{p.nome}</li>)}
</ul>
);
}Quando você precisa de "use client"
Um componente só precisa da diretiva "use client" quando ele usa algo que só existe no navegador: useState, useEffect, onClick, localStorage, qualquer evento de interação.
"use client";
import { useState } from "react";
export function ContadorDeLikes({ inicial }: { inicial: number }) {
const [likes, setLikes] = useState(inicial);
return <button onClick={() => setLikes((n) => n + 1)}>❤ {likes}</button>;
}Os dois convivem na mesma árvore
Um Server Component pode renderizar um Client Component como filho (o contrário — Client importando Server direto — não funciona). Na prática: busque o dado no servidor, passe como prop, e isole a interatividade num componente filho pequeno e marcado com "use client" — em vez de marcar a página inteira.
import { ContadorDeLikes } from "./contador-de-likes";
export default async function ProdutosPage() {
const produtos = await buscarProdutosNoBanco(); // roda no servidor
return (
<ul>
{produtos.map((p) => (
<li key={p.id}>
{p.nome} <ContadorDeLikes inicial={p.likes} /> {/* só esse pedaço vira JS no navegador */}
</li>
))}
</ul>
);
}Exercício
Um formulário de busca com um <input onChange> precisa de "use client"? E a página que lista os resultados da busca, que só recebe o termo e busca no banco?