Capítulo 32 de 54

force-dynamic no Next.js: Por Que Evitar em Páginas Públicas e Adotar em Painéis Admin

No desenvolvimento com o Next.js App Router, poucas linhas de código causam tanto impacto no desempenho e na infraestrutura quanto o modificador de rota:

export const dynamic = "force-dynamic";

Para quem está começando ou vem do mundo tradicional de servidores Node.js (onde toda requisição bate no banco de dados), essa instrução parece a solução mais simples para garantir que a tela sempre exiba os dados mais recentes. Afinal, ela desativa qualquer cache estático e instrui o servidor a renderizar o componente em tempo real a cada requisição HTTP (Server-Side Rendering puro).

No entanto, no ecossistema corporativo moderno com Vercel e Supabase, utilizar force-dynamic no lugar errado é a receita clássica para derrubar bancos de dados, gerar faturas exorbitantes de nuvem e destruir as métricas de Core Web Vitals (como TTFB e LCP).

Neste manual, vamos dissecar quando essa diretiva é um veneno arquitetural e exatamente onde ela se torna um escudo de segurança obrigatório.


1. O Perigo Mortal de Usar force-dynamic em Páginas Públicas

Imagine uma página pública de alto tráfego: a página inicial do seu produto, um catálogo de e-commerce com milhares de itens ou os artigos do seu blog institucional.

Ao adicionar export const dynamic = "force-dynamic" nessas rotas:

  1. A Malha de Borda (Edge CDN) É Anulada: A Vercel possui centenas de servidores espalhados pelo planeta capazes de responder a requisições em menos de 30 milissegundos. Ao forçar renderização dinâmica, a requisição é obrigada a furar a CDN e bater em uma função serverless centralizada para reconstruir o HTML do zero.
  2. Degradação Violenta do TTFB (Time to First Byte): O usuário precisa esperar a função inicializar (cold start), conectar ao banco Postgres, executar a query SQL, renderizar a árvore de componentes e devolver o payload. O tempo de resposta salta de míseros 40ms para 600ms–1500ms.
  3. Colapso de Conexões no Banco de Dados: Se a sua empresa lançar uma campanha de marketing e receber 5.000 acessos simultâneos, serão 5.000 requisições simultâneas forçando conexões ao Supabase Postgres. Mesmo com poolers de conexão como o Supavisor, o consumo de CPU do banco atinge 100%, gerando lentidão generalizada ou queda da aplicação.

O Padrão Ouro para Páginas Públicas: ISR e On-Demand Revalidation

Páginas públicas devem ser estáticas por padrão (export const dynamic = "auto" ou "error"). Para dados que sofrem atualizações frequentes (como alteração de preços ou novos posts), utiliza-se o Incremental Static Regeneration (ISR) com On-Demand Revalidation:

  • O usuário sempre recebe o HTML instantâneo do cache da borda.
  • Quando um registro muda no Supabase, um Database Trigger chama silenciosamente a rota de revalidação da Vercel (revalidatePath ou revalidateTag).
  • A Vercel reconstrói a página uma única vez em background com custo praticamente zero de banco de dados.

2. Onde o force-dynamic É ESTRITAMENTE OBRIGATÓRIO: Telas Administrativas

Se em páginas públicas o force-dynamic é proibido, dentro do Painel de Controle Corporativo (Admin) ele se torna mandatório e inegociável.

Considere rotas autenticadas de gestão, tais como:

  • /admin/financeiro
  • /dashboard/usuarios
  • /audit/logs
  • Telas de parametrização e permissões (RBAC)

Por Que Painéis Administrativos Devem Ser force-dynamic?

1. Prevenção de Vazamento de Cache (Cross-User Data Leaks)

Se um painel administrativo for acidentalmente renderizado de forma estática ou com cache compartilhado na CDN, o Administrador A pode visualizar dados em cache correspondentes à sessão do Administrador B. A diretiva force-dynamic garante que a renderização ocorra sob demanda, extraindo os cookies da requisição atual e respeitando estritamente a identidade de quem está logado.

2. Execução Real de Políticas de Segurança (Row Level Security - RLS)

No Supabase, as permissões de acesso residem no banco de dados através de políticas RLS atreladas ao token JWT do usuário autenticado. Para que o Postgres aplique a cláusula auth.uid() ou cheque se o usuário possui a role admin, a requisição deve ser feita em tempo real pelo servidor a cada carregamento da tela:

// src/app/admin/dashboard/page.tsx
import { createServerClient } from "@/lib/supabase/server";

// OBRIGATÓRIO: Garante que nenhuma resposta de admin seja compartilhada ou congelada
export const dynamic = "force-dynamic";

export default async function AdminDashboardPage() {
  const supabase = await createServerClient();
  
  // A query é executada em tempo real com o token do administrador atual
  const { data: auditLogs } = await supabase
    .from("audit_logs")
    .select("*")
    .order("created_at", { ascending: false })
    .limit(50);

  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold">Auditoria do Sistema</h1>
      {/* Renderização dos logs atualizados em tempo real */}
    </div>
  );
}

3. Auditoria e Integridade Imediata

Um operador ou gestor de suporte não pode tomar decisões com base em dados em cache de 60 segundos atrás. Se uma transação financeira for estornada ou um usuário for bloqueado, o painel precisa refletir esse estado com fidelidade absoluta de zero milissegundos. Como o volume de administradores simultâneos é uma fração ínfima do tráfego público, o banco suporta essas consultas dinâmicas com folga.


3. Matriz Arquitetural de Decisão

Para não restar nenhuma dúvida na hora de estruturar suas rotas, adote esta matriz simples:

Tipo de Rota Exemplo Estratégia de Cache Uso de force-dynamic
Landing Pages / Institucional /, /sobre, /precos Estático (SSG) PROIBIDO
Catálogo / Blog / E-commerce /blog/[slug], /produtos ISR + On-Demand Webhook PROIBIDO
Dashboards de Clientes /app/dashboard, /minha-conta Server Components dinâmicos ou SWR ⚠️ Opcional (avaliar SWR/Realtime)
Painel de Gestão e Admin /admin/**, /audit/** SSR em tempo real sob JWT ESTRITAMENTE OBRIGATÓRIO
Rotas de Webhook e Checkout /api/webhooks/stripe Rota Dinâmica ✅ Nativamente Dinâmico (POST)

Conclusão

Arquitetura de software de elite não é sobre seguir receitas cegas, mas sobre compreender o custo computacional e de segurança de cada linha declarada.

Proteja suas páginas públicas com o escudo do cache e do ISR para escalar sem limites de custos, e utilize o force-dynamic onde a soberania dos dados em tempo real e a confidencialidade das credenciais de administração forem a prioridade máxima.