This cheatsheet outlines 29 common mistakes, explaining why they're problematic and how to fix them with practical, best-practice solutions. Use this as a checklist before your next PR, during code reviews, or as you build your Next.js application to ensure you're leveraging the framework effectively.
"use client" at the top of a root page component forces the entire component tree to render on the client, negating all performance benefits of Server Components. Often done unnecessarily due to misunderstanding architecture.get Calls Inside a Server Actions File"use server" becomes a public HTTP endpoint. Placing data fetching (get) functions here unnecessarily exposes them and potentially sensitive data.lib/data.ts or lib/cart-server.ts). Only functions intended for mutations should reside in "use server" files./api/...) for simple GET requests that could be handled directly by Server Components. This adds unnecessary boilerplate, separate API management, and often forces the use of client components for state management.async Server Component. This reduces code, eliminates separate API routes, and keeps logic closer to where it's used. Use Suspense for loading states instead of useState.<Suspense> boundary directly around the async function call itself will not trigger the loader. It can also lead to errors if cache components are enabled and uncached data is accessed outside Suspense.<Suspense> boundary one level below the async data fetching logic, wrapping the component that consumes the fetched data. This ensures the loader displays correctly while the data is being prepared.