← cd ../skills
$ cat ~/skills/nextjs-checklist
Audit a Next.js App Router project against the official production checklist. Checks routing, rendering, data fetching, caching, security, SEO, accessibility, type safety, and pre-production readiness.
author: Val
markdown
---
name: nextjs-checklist
description: Audit a Next.js App Router project against the official production checklist. Checks routing, rendering, data fetching, caching, security, SEO, accessibility, type safety, and pre-production readiness.
---
# Next.js Production Checklist Audit
Audit the current Next.js App Router project for production readiness. Walk through every category below, inspect the actual project files, and report findings.
## Instructions
1. Identify the project root (look for `next.config.*`, `package.json` with `next` dependency, and `app/` directory).
2. For each category, run the file-level checks described. Use Glob, Grep, and Read tools to inspect the codebase.
3. Assign a status to each item:
- **✅** - Correctly implemented
- **⚠️** - Partially implemented or could be improved
- **❌** - Missing or incorrectly implemented
- **N/A** - Not applicable to this project
4. After all checks, produce a **Summary Table** and a **Prioritized Fix List**.
---
## 1. Routing & Rendering
### 1.1 Layouts
- Check that `app/layout.tsx` (root layout) exists and wraps children with `<html>` and `<body>` tags.
- Look for nested `layout.tsx` files in route segments for shared UI.
- Verify layouts do NOT unnecessarily re-render (no client-side state at top level without reason).
### 1.2 Link Component
- Grep for `<a href=` in `app/**/*.{tsx,jsx}` — internal links should use `next/link` (`<Link>`) instead of bare `<a>` tags.
- Confirm `<Link>` imports come from `"next/link"`.
### 1.3 Error Handling
- Check for `app/error.tsx` (root error boundary) — must be a Client Component (`"use client"`).
- Check for `app/global-error.tsx` for catching errors in the root layout.
- Look for nested `error.tsx` files in important route segments.
### 1.4 Client / Server Boundaries
- Grep for `"use client"` directives. Verify they are placed as deep in the component tree as possible (leaf components), not at the top of the tree.
- Confirm Server Components (files without `"use client"`) do not import client-only APIs (`useState`, `useEffect`, `useRef`, browser globals).
- Check that Client Components do not import server-only modules (look for `import "server-only"` usage in server modules).
### 1.5 Dynamic APIs & Route Segment Config
- Search for `cookies()`, `headers()`, `searchParams`, `useSearchParams()` usage — these opt routes into dynamic rendering.
- Check for `export const dynamic`, `export const revalidate`, or `export const runtime` in page/layout files when static behavior is intended.
---
## 2. Data Fetching & Caching
### 2.1 Server-Side Fetching
- Verify data fetching happens in Server Components or Route Handlers, not in Client Components via `useEffect` for initial data.
- Look for `fetch()` calls in server components and check caching options (`{ cache: "force-cache" }`, `{ next: { revalidate: N } }`).
### 2.2 Route Handlers
- Check `app/**/route.ts` files. Confirm they use proper HTTP method exports (`GET`, `POST`, etc.).
- Verify Route Handlers validate input and return appropriate status codes.
### 2.3 Streaming & Suspense
- Look for `loading.tsx` files in route segments (enables streaming for that segment).
- Check for `<Suspense>` boundaries wrapping slow data-fetching components.
- Verify fallback UI is provided in Suspense boundaries.
### 2.4 Parallel & Sequential Fetching
- In Server Components with multiple data needs, check for parallel fetching patterns (`Promise.all`) vs. sequential waterfalls.
### 2.5 Caching Strategy
- Check `next.config.*` for any global fetch cache configuration.
- Look for `revalidatePath()` or `revalidateTag()` usage in Server Actions or Route Handlers for on-demand revalidation.
- Check for `unstable_cache` or `cache()` from React for caching non-fetch data.
---
## 3. UI & Accessibility
### 3.1 Forms & Mutations
- Check for Server Actions (`"use server"`) used in form handling.
- Look for `useFormStatus` and `useFormState` (or `useActionState`) for pending/error UI on forms.
- Verify forms have proper `action` attributes pointing to Server Actions.
### 3.2 Error & Not Found UI
- Confirm `app/not-found.tsx` exists for custom 404 pages.
- Confirm `notFound()` is called in pages/layouts when data is missing.
- Check error boundaries provide user-friendly messages and recovery options.
### 3.3 Font Optimization
- Check for `next/font` usage (`next/font/google` or `next/font/local`) instead of external `<link>` tags for fonts.
- Verify font variables are applied to `<html>` or `<body>` in the root layout.
### 3.4 Image Optimization
- Grep for `<img` tags — should use `next/image` (`<Image>`) instead.
- Verify `<Image>` components include `width`/`height` or `fill` prop.
- Check `next.config.*` for `images.remotePatterns` if external images are used.
### 3.5 Script Optimization
- Look for `<script>` tags in components — should use `next/script` (`<Script>`) with appropriate `strategy` (`lazyOnload`, `afterInteractive`, etc.).
### 3.6 Accessibility Linting
- Check `package.json` or ESLint config for `eslint-plugin-jsx-a11y` (included by default with `eslint-config-next`).
- Verify ESLint config extends `"next/core-web-vitals"` or `"next"`.
---
## 4. Security
### 4.1 Data Tainting
- Check for `experimental.taint` in `next.config.*` (prevents sensitive objects from being passed to Client Components).
### 4.2 Server Actions
- Verify Server Actions validate and sanitize input (look for validation libraries like `zod` in action files).
- Check that Server Actions are defined in dedicated files with `"use server"` at the top, or inline with `"use server"` inside the function body.
- Look for auth checks at the start of Server Actions.
### 4.3 Environment Variables
- Verify sensitive env vars do NOT start with `NEXT_PUBLIC_` (grep `.env*` files).
- Check for `env.mjs` or similar runtime validation (e.g., `@t3-oss/env-nextjs`, `zod` schema).
- Confirm `.env*.local` is in `.gitignore`.
### 4.4 Content Security Policy
- Look for CSP headers in `middleware.ts` or `next.config.*` headers config.
- Check for `nonce` generation if inline scripts are used.
### 4.5 Security Headers
- Check `next.config.*` `headers()` or `middleware.ts` for security headers:
- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: DENY` or `SAMEORIGIN`
- `Referrer-Policy`
- `Permissions-Policy`
- `Strict-Transport-Security` (HSTS)
---
## 5. Metadata & SEO
### 5.1 Metadata API
- Check for `export const metadata` or `export async function generateMetadata()` in `app/layout.tsx` and `app/page.tsx`.
- Verify title, description, and openGraph fields are set.
- Look for `metadataBase` in root layout for resolving relative OG URLs.
### 5.2 Open Graph Images
- Check for `opengraph-image.tsx` / `opengraph-image.png` (or `.jpg`) files in `app/` for auto-generated OG images.
- Alternatively, verify OG image URLs in metadata exports.
### 5.3 Sitemap
- Look for `app/sitemap.ts` or `app/sitemap.xml` for dynamic/static sitemap generation.
### 5.4 Robots
- Look for `app/robots.ts` or `app/robots.txt` (or `public/robots.txt`).
- Verify it allows/disallows appropriate paths.
### 5.5 Structured Data
- Check for JSON-LD (`<script type="application/ld+json">`) in pages for rich search results.
---
## 6. Type Safety
### 6.1 TypeScript Strict Mode
- Read `tsconfig.json` and verify `"strict": true` is set in `compilerOptions`.
### 6.2 Next.js TypeScript Plugin
- Check `tsconfig.json` for `"plugins": [{ "name": "next" }]` in `compilerOptions` (enables enhanced type checking for Next.js APIs).
### 6.3 Typed Routes (optional)
- Check `next.config.*` for `experimental.typedRoutes` — provides type-safe `<Link href>`.
---
## 7. Pre-Production
### 7.1 Build Check
- Note whether `next build` has been run successfully (check for `.next/` directory presence and any build error logs).
- Flag if `next.config.*` has `eslint.ignoreDuringBuilds: true` or `typescript.ignoreBuildErrors: true`.
### 7.2 Bundle Analysis
- Check `package.json` for `@next/bundle-analyzer` dependency.
- Look for bundle analyzer configuration in `next.config.*`.
### 7.3 Core Web Vitals
- Check for web vitals reporting setup (e.g., `useReportWebVitals` from `next/web-vitals`, or analytics integration in root layout).
- Look for `@next/third-parties` usage for optimized third-party script loading (Google Analytics, GTM, etc.).
---
## Output Format
After completing all checks, produce the report in this format:
### Summary Table
```
Category | Pass | Warn | Fail | N/A
--------------------------|------|------|------|----
1. Routing & Rendering | X | X | X | X
2. Data Fetching & Caching| X | X | X | X
3. UI & Accessibility | X | X | X | X
4. Security | X | X | X | X
5. Metadata & SEO | X | X | X | X
6. Type Safety | X | X | X | X
7. Pre-Production | X | X | X | X
```
### Detailed Results
For each item, report:
```
[STATUS] Category.Item — Item Name
Finding: What was found (or not found).
File(s): path/to/relevant/file.tsx:lineNumber
Fix: Specific action to take (for Warn/Fail items).
```
### Prioritized Fixes
List all Fail items first, then Warn items, ordered by impact:
1. **[Fail]** Most critical issue — what to fix and why
2. **[Fail]** Next critical issue — ...
3. **[Warn]** Important improvement — ...
Focus fixes on items that affect security, correctness, and Core Web Vitals first, then SEO and developer experience.
For each item, suggest the action needed to fix it (if a fix is needed). Then ask the user which of these fixes they want you to implement (allow selecting multiple).