ui
Frontend
React, Next.js, TypeScript, Tailwind e padrões de componentização.
Visão geral do ecossistema
core
⚛️
React 19
Server Components, use() hook, Actions, melhorias de performance e novo compilador.
framework
▲
Next.js 15
App Router estável, Turbopack, PPR (Partial Prerendering), React 19 suporte nativo.
lang
🔷
TypeScript
Tipagem estática, interfaces, generics, type inference. Padrão para projetos sérios.
styles
🎨
Tailwind CSS
Utility-first CSS framework. Design tokens, responsividade, dark mode sem CSS customizado.
state
📦
Zustand / Jotai
Estado global simples e performático. Alternativas leves ao Redux para projetos modernos.
data
🔄
TanStack Query
Data fetching, cache, sync e servidor state management. Elimina boilerplate de useEffect+fetch.
App Router vs Pages Router
O App Router (Next.js 13+) é o modelo atual e recomendado. Pages Router ainda funciona mas está em modo de manutenção.
- App Router usa React Server Components por padrão
- Layouts aninhados, loading.tsx, error.tsx nativos
- generateStaticParams para exportação estática
- generateMetadata para SEO por rota
Estrutura App Router
app/
layout.tsx ← layout raiz
page.tsx ← rota /
[locale]/
layout.tsx ← layout do locale (html lang, providers)
page.tsx ← rota /[locale]
dashboard/
layout.tsx ← layout aninhado
page.tsx ← rota /[locale]/dashboard
loading.tsx ← fallback de Suspense automático
error.tsx ← Error Boundary automático
not-found.tsx ← 404 da rotaℹ️ Info
Server Components são renderizados no servidor e não têm acesso a hooks, eventos ou browser APIs. Para essas features, adicione
"use client" no topo do componente.Padrões de componentização
Hierarquia de componentes
- Pages : recebem params/searchParams, orquestram layout e fetch de dados
- Layouts : estrutura persistente entre navegações
- Feature Components : encapsulam lógica de domínio
- UI Components : puros, reutilizáveis, sem estado de aplicação
- Hooks : lógica stateful reutilizável
Exemplo de componente UI puro
// src/components/ui/Badge.tsx
type BadgeVariant = "default" | "success" | "warning" | "danger";
const variantClasses: Record<BadgeVariant, string> = {
default: "bg-slate-800 text-slate-300 border-slate-700",
success: "bg-green-950 text-green-400 border-green-800",
warning: "bg-yellow-950 text-yellow-400 border-yellow-800",
danger: "bg-red-950 text-red-400 border-red-800",
};
type BadgeProps = {
children: React.ReactNode;
variant?: BadgeVariant;
};
export function Badge({ children, variant = "default" }: BadgeProps) {
return (
<span className={`inline-flex items-center text-xs font-medium px-2 py-0.5 rounded border ${variantClasses[variant]}`}>
{children}
</span>
);
}