← 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.

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).