Next.js — Checklists¶
OWNER: floris, floor
ALSO_USED_BY: urszula, maxim, alexander
LAST_VERIFIED: 2026-03-26
GE_STACK_VERSION: next@15.5.x
Overview¶
Machine-parseable checklists for Next.js projects. Run through relevant phase
before proceeding. Items are NEVER removed — only marked DEPRECATED if obsolete.
PRE-IMPLEMENTATION CHECKLIST (new project setup)¶
- [ ] CHECK:
nextversion pinned to 15.5.x in package.json (not floating ^/~) - [ ] CHECK:
reactandreact-dompinned to 19.x - [ ] CHECK: TypeScript strict mode enabled in tsconfig.json
- [ ] CHECK:
output: "standalone"set in next.config.ts - [ ] CHECK:
turbopackused for dev (next dev --turbopackin package.json scripts) - [ ] CHECK: Tailwind CSS + shadcn/ui initialized
- [ ] CHECK: Project structure follows GE convention (src/app, src/components, src/lib)
- [ ] CHECK: Route groups created for (public) vs (dashboard) separation
- [ ] CHECK: Root layout has
<html lang>attribute set correctly - [ ] CHECK: Root layout has metadata with
title.template - [ ] CHECK:
next/fontconfigured for self-hosted fonts (no external CDN) - [ ] CHECK:
.env.localin.gitignore - [ ] CHECK:
.dockerignoreexcludes node_modules, .next, .env.local, .git - [ ] CHECK:
import "server-only"added to database/secret modules - [ ] CHECK: ESLint configured with
next/core-web-vitalspreset - [ ] CHECK: Security headers configured in next.config.ts
IF_SKIPPED: security audit failure, ISO 27001 non-compliance
PRE-COMMIT CHECKLIST (every commit with Next.js changes)¶
- [ ] CHECK: no
"use client"on page.tsx or layout.tsx files - [ ] CHECK:
"use client"is first line where present (no comments/blanks above) - [ ] CHECK: Server Actions validate all input with Zod
- [ ] CHECK: Zod errors accessed via
.issuesnot.errors(Zod v4) - [ ] CHECK:
redirect()not called inside try/catch blocks - [ ] CHECK:
paramsandsearchParamsare awaited (Next.js 15 async change) - [ ] CHECK:
useSearchParams()wrapped in Suspense boundary - [ ] CHECK: imports from
next/navigationnotnext/router - [ ] CHECK: metadata export or generateMetadata() on every page
- [ ] CHECK: no
NEXT_PUBLIC_env vars containing secrets - [ ] CHECK: no raw
<img>tags — usenext/image - [ ] CHECK:
useActionStatenotuseFormState(deprecated in React 19) - [ ] CHECK: independent data fetches use
Promise.all()not sequential await - [ ] CHECK: revalidateTag/revalidatePath called after mutations in Server Actions
IF_SKIPPED: stale data shown to users after form submissions
PRE-DEPLOY CHECKLIST (before deploying to k3s)¶
- [ ] CHECK:
pnpm buildcompletes without errors or warnings - [ ] CHECK: no red/yellow bundle size warnings in build output
- [ ] CHECK: First Load JS (shared) ≤ 90KB gzipped
- [ ] CHECK: no page exceeds 50KB individual First Load JS
- [ ] CHECK: Docker multi-stage build produces standalone image
- [ ] CHECK: Docker image runs as non-root user (nextjs:nodejs)
- [ ] CHECK:
HOSTNAME=0.0.0.0set in k8s deployment env - [ ] CHECK: health check endpoint configured and responding
- [ ] CHECK: resource limits set in k8s deployment (CPU + memory)
- [ ] CHECK: all env vars present in k8s secrets/configmaps
- [ ] CHECK: no
.env.localor secrets baked into Docker image - [ ] CHECK:
output: "standalone"confirmed in next.config.ts - [ ] CHECK: static assets have immutable cache headers in next.config
- [ ] CHECK: security headers present (X-Frame-Options, CSP, X-Content-Type-Options)
IF_SKIPPED: ISO 27001 audit failure - [ ] CHECK: patched against CVE-2025-29927 (self-hosted middleware bypass)
IF_SKIPPED: critical auth bypass vulnerability
ADDED_FROM: security-audit-2025-03, middleware header manipulation
PRE-RELEASE CHECKLIST (before client go-live)¶
- [ ] CHECK: Core Web Vitals pass — LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1
- [ ] CHECK: Lighthouse score ≥ 90 on all key pages (Performance, Accessibility, Best Practices, SEO)
- [ ] CHECK: all pages have proper metadata (title, description, OG tags)
- [ ] CHECK: error.tsx boundaries at all critical route segments
- [ ] CHECK: not-found.tsx present for custom 404 pages
- [ ] CHECK: loading.tsx or Suspense fallbacks on all data-fetching pages
- [ ] CHECK: auth verified at middleware + Server Component + Server Action layers
IF_SKIPPED: auth bypass possible (CVE-2025-29927 lesson)
ADDED_FROM: security-audit-2025-03, defense-in-depth requirement - [ ] CHECK: forms work with JavaScript disabled (progressive enhancement)
- [ ] CHECK: WebVitals monitoring active in production (useReportWebVitals)
- [ ] CHECK: EU data sovereignty verified — no external analytics/CDN outside EU
IF_SKIPPED: GDPR non-compliance, client contract violation - [ ] CHECK: robots.txt and sitemap.xml configured for SEO pages
- [ ] CHECK: all images optimized (hero ≤ 200KB, thumbs ≤ 50KB)
- [ ] CHECK: no console.log or debug output in production build
- [ ] CHECK: error tracking configured and verified (EU-hosted service)
- [ ] CHECK: rate limiting active on public API routes and auth endpoints
ADDED_FROM: admin-ui-2026-02, brute force prevention
Cross-References¶
READ_ALSO: wiki/docs/stack/nextjs/index.md
READ_ALSO: wiki/docs/stack/nextjs/pitfalls.md
READ_ALSO: wiki/docs/stack/nextjs/performance.md
READ_ALSO: wiki/docs/stack/nextjs/middleware.md