Skip to content

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: next version pinned to 15.5.x in package.json (not floating ^/~)
  • [ ] CHECK: react and react-dom pinned to 19.x
  • [ ] CHECK: TypeScript strict mode enabled in tsconfig.json
  • [ ] CHECK: output: "standalone" set in next.config.ts
  • [ ] CHECK: turbopack used for dev (next dev --turbopack in 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/font configured for self-hosted fonts (no external CDN)
  • [ ] CHECK: .env.local in .gitignore
  • [ ] CHECK: .dockerignore excludes node_modules, .next, .env.local, .git
  • [ ] CHECK: import "server-only" added to database/secret modules
  • [ ] CHECK: ESLint configured with next/core-web-vitals preset
  • [ ] 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 .issues not .errors (Zod v4)
  • [ ] CHECK: redirect() not called inside try/catch blocks
  • [ ] CHECK: params and searchParams are awaited (Next.js 15 async change)
  • [ ] CHECK: useSearchParams() wrapped in Suspense boundary
  • [ ] CHECK: imports from next/navigation not next/router
  • [ ] CHECK: metadata export or generateMetadata() on every page
  • [ ] CHECK: no NEXT_PUBLIC_ env vars containing secrets
  • [ ] CHECK: no raw <img> tags — use next/image
  • [ ] CHECK: useActionState not useFormState (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 build completes 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.0 set 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.local or 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