ae39e45460
NOVAS SKILLS: - next-best-practices v0.1.0 (CLEAN) — Next.js App Router, RSC, caching, data - nextjs-patterns v1.0.0 (CLEAN) — Next.js 15: Server Actions, route handlers - vite v1.0.0 (CLEAN) — env vars, aliases, proxy, CJS compat - uncle-bob v1.0.0 (CLEAN) — Clean Code, SOLID, Clean Architecture - clean-code-review v1.0.0 (CLEAN) — naming, guard clauses, anti-patterns, refactoring - vue v1.0.0 (CLEAN) — Vue framework - vue-composition-api-best-practices v1.0.0 (CLEAN) — composables, Pinia, reactivity BIBLIOTECA INTELIGENTE libs/ (10 dominios, 11 arquivos): - typescript/ — TS safe + generics gotchas - react/ — Next.js App Router + Vite config - vue/ — Composition API + Pinia - linux/ — System diagnostic cheatsheet - database/ — PostgreSQL + MySQL patterns - browser/ — Chromium CLI + E2E testing - security/ — SAST audit (OWASP Top 10) - best-practices/ — Clean Code + SOLID + Clean Architecture - deploy/ — Docker multi-stack + OpenClaw ops - + INDEX.md como guia de navegacao .learnings/ — LRN-20260519-003 criado (biblioteca compartilhada)
3.7 KiB
3.7 KiB
name, description
| name | description |
|---|---|
| nextjs-patterns | Apply Next.js 15 best practices and modern patterns including App Router, Server Components, Server Actions, caching strategies, and performance optimization. Use when building or reviewing Next.js 15 applications to ensure idiomatic, production-ready code. |
Next.js 15 Best Practices
Core Principles
- Default to Server Components — only add
"use client"when you need interactivity or browser APIs - Colocate by feature — keep components, hooks, and utils near the routes that use them
- Type everything — leverage TypeScript with strict mode enabled
- Cache deliberately — understand the four caching layers and opt in/out explicitly
Project Structure
app/
(marketing)/ # route group: no URL segment
page.tsx
(dashboard)/
layout.tsx
[id]/
page.tsx
api/
route.ts
components/
ui/ # shared, "dumb" UI components
features/ # feature-specific components
lib/
db.ts # database client (singleton)
auth.ts # auth helpers
utils.ts
Server vs. Client Components
// ✅ Server Component (default) — runs on server, no JS sent to client
export default async function ProductList() {
const products = await db.product.findMany()
return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>
}
// ✅ Client Component — only when needed
"use client"
import { useState } from "react"
export function Counter() {
const [n, setN] = useState(0)
return <button onClick={() => setN(n + 1)}>{n}</button>
}
Data Fetching Patterns
// Parallel fetching (avoid sequential waterfalls)
export default async function Dashboard() {
const [user, stats] = await Promise.all([
fetchUser(),
fetchStats(),
])
return <View user={user} stats={stats} />
}
// fetch with cache control
const data = await fetch("https://api.example.com/data", {
next: { revalidate: 60 }, // ISR: revalidate every 60s
// cache: "no-store" // always fresh
// cache: "force-cache" // static, until manual revalidation
})
Server Actions
// app/actions.ts
"use server"
import { revalidatePath } from "next/cache"
export async function createPost(formData: FormData) {
const title = formData.get("title") as string
await db.post.create({ data: { title } })
revalidatePath("/posts")
}
// app/posts/new/page.tsx
import { createPost } from "../actions"
export default function NewPost() {
return (
<form action={createPost}>
<input name="title" />
<button type="submit">Create</button>
</form>
)
}
Metadata & SEO
// Static metadata
export const metadata = {
title: "My App",
description: "...",
}
// Dynamic metadata
export async function generateMetadata({ params }) {
const post = await fetchPost(params.slug)
return { title: post.title, description: post.excerpt }
}
Error & Loading States
// app/posts/loading.tsx — automatic Suspense boundary
export default function Loading() {
return <Skeleton />
}
// app/posts/error.tsx — automatic error boundary
"use client"
export default function Error({ error, reset }) {
return <button onClick={reset}>Retry: {error.message}</button>
}
Performance Checklist
- Images use
next/imagewith explicitwidth/height - Fonts use
next/font(zero layout shift) - Dynamic imports for heavy client components:
dynamic(() => import(...)) generateStaticParamsfor known dynamic routes- Bundle analyzer run:
ANALYZE=true next build - Partial Prerendering (PPR) considered for mixed static/dynamic pages
References
See references/ folder for routing patterns, caching deep-dive, and migration guide.