Keep 'use client' at the leaf: default to Server Components
Prefer Server Components for pages/layouts and move interactivity to small leaf Client Components. Only add 'use client' where browser APIs or event handlers are strictly necessary.
stack-nextjsstack-react+2
High
Make fetch caching explicit in Server Components
For dynamic data use { cache: 'no-store' } or file-level dynamic = 'force-dynamic'. For ISR use { next: { revalidate: N, tags: [...] } }.
stack-nextjsstack-react+2
High
Middleware only for light auth/rewrites
Keep middleware fast and side-effect free (no DB writes). Narrow the matcher and skip static assets. Use Route Handlers for heavy logic.
stack-nextjsstack-react+2
High
Never expose secrets to the client
Read secrets (process.env.*) only in Server Components, Route Handlers, or server actions. Client Components must use ONLY NEXT_PUBLIC_* variables.
stack-nextjsstack-react+3
High
Read headers/cookies only on the server
Use headers() and cookies() in Server Components, Route Handlers, or server actions; never in Client Components.
stack-nextjsstack-react+2
High
Revalidate after mutations to keep UI cache coherent
After server-side mutations, call revalidatePath or revalidateTag to refresh cached RSC data.
stack-nextjsstack-react+2
High
Use next/image with explicit dimensions and alt
Always use the Next.js Image component for images with width/height (or fill) and meaningful alt text. Avoid plain <img> for app assets.
stack-nextjsstack-react+3
High
Use Route Handlers in app/api with NextResponse
Prefer app/api route handlers over legacy pages/api. Return NextResponse.json, validate input, and handle allowed HTTP methods explicitly.
stack-nextjsstack-react+2
High
Validate inputs on the server (zod) in Route Handlers/Actions
Validate and sanitize all request bodies and search params on the server using a schema (e.g., zod). Reject invalid payloads with proper status.
stack-nextjsstack-react+2
Low
Dynamic import for heavy client-only widgets
Use next/dynamic with { ssr: false } for large client-only components (maps, editors) and provide a lightweight loading fallback.
stack-nextjsstack-react+2
Low
Internationalize user-facing text with next-intl or next-i18next
Do not hardcode user-visible strings in pages/layouts. Use an i18n library integrated with App Router and load dictionaries on the server.
stack-nextjsstack-react+2
Low
Model mutations with Server Actions when feasible
For simple form submissions from RSC, use server actions with schema validation and then revalidate paths/tags. Avoid client fetch for trivial mutations.
stack-nextjsstack-react+3
Low
Prefer next/link for internal navigation
Use <Link> from 'next/link' for internal routes; reserve <a> only for external URLs or downloadable assets.
stack-nextjsstack-react+2
Low
Provide loading.tsx and error.tsx per segment
For async routes, add loading.tsx for suspense fallbacks and error.tsx for boundaries. Use notFound() for 404 states.
stack-nextjsstack-react+2
Low
Use generateStaticParams for SSG on dynamic routes
When statically prebuilding dynamic segments, implement generateStaticParams and validate params; fall back to notFound() for invalid slugs.
stack-nextjsstack-react+2
Low
Use Metadata API instead of <Head>
Declare SEO metadata via export const metadata or generateMetadata; avoid manual <Head> in App Router.
stack-nextjsstack-react+2
Low
Use next/font for fonts (no <link> to external CDNs)
Load fonts via next/font (google or local) and apply on html/body; avoid runtime <link> to fonts that cause FOUT/CLS.
stack-nextjsstack-react+2
Low
Use next/script safely and avoid inline scripts
For third-party scripts, use <Script> with an appropriate strategy and onLoad callbacks. Avoid dangerouslySetInnerHTML for scripts.
stack-nextjsstack-react+2
Low
Use redirect() and notFound() from next/navigation
Prefer redirect() and notFound() over manual 302/404 handling and custom components in App Router.