Server Components no Next.js 15: o que mudou na prática
Author
Kayro Gomes
Date Published

Texto opinativo: o que vem a seguir é minha leitura depois de 6 meses com Next.js 15 em produção. Se discordar, me chama no GitHub Issues do projeto.
O que mudou de verdade no 15
Muita gente ainda acha que React Server Components é "o Next faz a query no servidor". Não é — é mais profundo. RSC muda o que conta como estado, o que conta como fetch, e o que conta como "render". Server Components rodam uma vez no servidor e enviam uma árvore serializada pro browser, sem JS hidratado desnecessário.
No 15, três mudanças foram sentidas de verdade no meu dia a dia:
1. async params e searchParams
Não é mais um objeto — é uma Promise. Toda página que recebia slug agora precisa de await. Parece pequeno, mas simplifica a coexistência com Suspense e elimina uma classe inteira de bugs onde devs tentavam tratar params como síncrono e quebravam em produção.
1type Args = {2 params: Promise<{ slug: string }>3 searchParams: Promise<{ [key: string]: string | string[] | undefined }>4}56export default async function PostPage({ params, searchParams }: Args) {7 const { slug } = await params8 const { ref } = await searchParams9 const post = await getPostBySlug(slug)10 return <PostArticle post={post} ref={ref} />11}
2. fetch cache mudou de default
fetch() em Server Components agora é cacheado por padrão, não no-store como era no 14. Isso é uma grande mudança: significa que chamar a mesma URL duas vezes na mesma renderização não dispara duas requests. Para o Payload, isso ajudou muito — múltiplas queries no mesmo post reaproveitam a cache.
3. Server Actions ficaram estáveis
Actions para mutação via form direto no server, sem API route, sem JS no client. O caso de uso que me pegou: o formulário de contato deste site. Antes: API route + fetch no client + loading state + error handling. Agora: <form action={submitContactForm}> e o Next faz o resto.
1// app/(frontend)/contato/page.tsx2async function submitContactForm(formData: FormData) {3 'use server'4 const submission = await payload.create({5 collection: 'form-submissions',6 data: {7 form: contactFormId,8 submissionData: Object.fromEntries(formData),9 },10 })11 revalidatePath('/contato')12 redirect('/contato?enviado=1')13}1415export default function ContatoPage() {16 return (17 <form action={submitContactForm} className="space-y-4">18 <input name="full-name" required placeholder="Seu nome" />19 <input name="email" type="email" required placeholder="Seu e-mail" />20 <textarea name="message" required placeholder="Sua mensagem" />21 <button type="submit">Enviar</button>22 </form>23 )24}
O que ainda me incomoda
O debug de Server Components ainda é pior que Client Components. O error stack aponta para o arquivo compilado, não pro source. A mensagem de erro às vezes esconde a query que falhou. Tudo melhor que em 2023, mas ainda me faz perder 30 min por semana.

Imagem de capa ilustrativa. Substitua no admin em Mídia.
Server Components são o futuro do React web. Ainda tem fricção (debug, error messages, curva de aprendizado), mas os ganhos em performance e DX são reais. Se você está começando um projeto novo em 2026, RSC não é mais opcional — é o caminho padrão.

Por que migrei meu portfólio para Payload CMS 3 + Next.js 15, e o que aprendi no processo (preview, mídia, deploy).

Branching de banco, preview por PR, e por que escolhi Neon Postgres para meu portfólio Next.js.