---
title: "Como estruturar projetos Next.js escaláveis com App Router"
slug: "como-estruturar-projetos-nextjs"
author: "Mateus Cavalcanti"
publishedAt: "2026-09-13T00:15:51.965Z"
updatedAt: "2026-09-13T00:15:52.185Z"
category: "Arquitetura"
tags:
  - "App Router"
  - "Arquitetura"
  - "Next.js"
  - "React"
  - "Server Actions"
---

# Como estruturar projetos Next.js escaláveis com App Router

A estrutura de um projeto Next.js com App Router precisa favorecer dois pilares fundamentais: **clareza e previsibilidade para o time** e **capacidade de evolução sustentável**.

O modelo de App Router é orientado a rotas, layouts compartilhados e componentes de servidor por padrão (*React Server Components*). Compreender como desenhar limites de arquitetura limpos é o que separa uma aplicação rápida e fácil de manter de um projeto com acoplamento e re-renderizações desnecessárias.

## Estrutura base recomendada

Adotar uma estrutura limpa na raiz da aplicação facilita a navegação e a separação de responsabilidades:

```txt
src/
  app/
    (site)/
      layout.tsx
      page.tsx
      blog/
        page.tsx
        [slug]/
          page.tsx
    api/
  components/
    ui/
    common/
  features/       # ou módulos de domínio (ex: auth, blog, checkout)
    blog/
      actions/
      components/
      hooks/
      schemas/
  lib/
    db/
    services/
    utils/
```

## Diretrizes práticas de arquitetura

1. **Rotas em `app/` apenas para composição**: Evite colocar regras de negócio pesadas dentro dos arquivos `page.tsx`. Use as páginas para coordenar data fetching e injetar props nos componentes.
2. **Server Components por padrão**: Não adicione `"use client"` a menos que precise de hooks de estado local (`useState`, `useReducer`), efeitos (`useEffect`), ouvintes de eventos do DOM ou bibliotecas que dependem do navegador.
3. **Mantenha os limites de cliente nas folhas da árvore**: Em vez de marcar uma página inteira como Client Component, isole apenas o botão ou widget interativo.
4. **Centralize conexões de infraestrutura em `lib/`**: Clientes de banco (como Prisma ou Drizzle), serviços de email e APIs de terceiros devem residir fora do escopo de rotas.

## Server Actions e Mutações de Dados

Com Server Actions, mutações de dados acontecem diretamente no servidor, eliminando a necessidade de criar endpoints de API avulsos apenas para receber formulários. No entanto, segurança e validação são inegociáveis:

```tsx
"use server";

import { z } from "zod";
import { revalidatePath } from "next/cache";

const CreateCommentSchema = z.object({
  postId: z.string().uuid(),
  author: z.string().min(2).max(50),
  content: z.string().min(5).max(1000),
});

export async function addCommentAction(formData: FormData) {
  const parsed = CreateCommentSchema.safeParse({
    postId: formData.get("postId"),
    author: formData.get("author"),
    content: formData.get("content"),
  });

  if (!parsed.success) {
    return { success: false, errors: parsed.error.flatten().fieldErrors };
  }

  // Execução no banco de dados com segurança
  await db.comment.create({ data: parsed.data });

  revalidatePath(`/blog/${parsed.data.postId}`);
  return { success: true };
}
```

## Checklist para manter o projeto saudável

- **Consistência de nomenclatura**: Mantenha convenções bem documentadas para pastas e arquivos.
- **Evite vazar segredos**: Utilize pacotes como `server-only` para garantir que módulos com chaves de API nunca sejam importados por componentes de cliente acidentalmente.
- **Tipagem estrita**: Compartilhe schemas (Zod) entre o backend/actions e os formulários no cliente.

Uma boa arquitetura não é a que usa o maior número de abstrações, mas a que permite que qualquer desenvolvedor encontre o que precisa e entregue código confiável com facilidade.
