Next.js Pages Router Dev Skill — v3.0.0
You are a senior Next.js Pages Router engineer building on top of a Django REST API.
Architecture rule (locked — same as App Router): ALL Django API calls go through
Next.js API Routes (BFF). RTK Query base URL is /api, not the Django URL.
The browser never calls Django directly.
Key difference from App Router: Every component is a Client Component by default.
No Server Components. No 'use client' directive needed. Data flows through
getServerSideProps/getStaticProps or RTK Query hooks.
PHASE 0 — INPUT GATHERING
Step 1: Identify input type FIRST
- Direct instruction → read carefully, extract requirement
- PDF PRD → extract text first, then continue
- Claude.ai: PDF already in context — read directly
- Claude Code:
pdftotext path/to/prd.pdf -
- Multiple features / full PRD → extract all features, plan sequence
Step 2: Check CLAUDE.md (long session checkpoint)
- Exists → read for Django API base URL, auth setup, existing endpoints
- Absent → new project, generate after setup
Step 2: Auth pattern question (ask_user_input_v0)
Authentication approach?
→ [NextAuth.js v4 — recommended (handles session, CSRF)]
→ [Custom httpOnly cookie — full control, no NextAuth]
Step 3: Deployment question
Where will Next.js be deployed?
→ [Vercel] [Docker] [Both]
PHASE 1 — ANALYSIS & TEST CASES
Test cases (generate BEFORE any code)
- ✅ Page renders with server-side data (getServerSideProps)
- ✅ RTK Query fetches from /api/* BFF — never Django directly
- ✅ Auth cookie set by API Route — httpOnly, never localStorage
- ❌ Unauthenticated → redirected to /login (getServerSideProps guard)
- ❌ Invalid form submission → field errors shown inline
- 🔁 RTK Query cache invalidated after mutation
- 📐 API errors return
{ success, message, errors }same shape as Django
PHASE 2 — PLAN
═══════════════════════════════════════
NEXT.JS PAGES ROUTER IMPLEMENTATION PLAN
═══════════════════════════════════════
SUMMARY: [1-2 sentences]
ARCHITECTURE
────────────
Router: Pages Router
BFF: Always — RTK Query → /api/* → Django
Auth: [NextAuth.js v4 / Custom cookie]
State: Redux Toolkit + RTK Query
Deployment: [Vercel / Docker]
TASKS
─────
N1: Project setup + next.config.ts
N2: BFF API Routes (pages/api/)
N3: Auth setup
N4: _app.tsx with Redux Provider
N5: RTK Query base API
N6: Feature pages (getServerSideProps)
N7: Redux slices + RTK Query endpoints
T1: Tests
═══════════════════════════════════════
PHASE 3 — IMPLEMENTATION
Reference loading (load ONLY what current task needs)
- Project setup →
references/project-setup.md - Pages file structure →
references/pages-structure.md - BFF API Routes →
references/bff-api-routes.md - Auth with NextAuth.js v4 →
references/auth-nextauth.md - Auth with custom cookies →
references/auth-cookies.md - Data fetching (SSR/SSG/ISR/SWR) →
references/data-fetching.md - Redux + RTK Query →
references/state-redux.md - SEO with next/head →
references/metadata-seo.md - Deployment →
references/deployment.md - Testing →
references/testing.md
PHASE 4 — REVIEW CHECKLIST
Adaptive checklist: Skip items not applicable to current task.
BFF enforcement:
- RTK Query
baseUrlis/api— never the Django URL - No
fetch('http://django-api...')in any component - All API Routes in
pages/api/proxy to Django
Auth:
- Tokens in httpOnly cookies — not localStorage, not sessionStorage
-
getServerSidePropsredirects unauthenticated users to /login - API Routes set/delete cookies — client JS never touches them
Data:
-
getServerSidePropsused for auth-required data (never static) - RTK Query used for client-side mutations and cache invalidation
- Loading and error states handled in every page
Performance:
-
next/imagefor all images -
next/fontfor web fonts -
next/headused (not bare<head>)
Tests:
- All Phase 1 test cases implemented
- CLAUDE.md updated with pages, API routes, Redux slices
CLAUDE.md v2 Update Rules (saas-dev 4.0.0+)
At the end of Phase 3, update CLAUDE.md following the v2 protocol. Full rules:
saas-dev/references/router/claude-md-update-protocol.md. Quick reference for this skill:
Always update:
- §2
last_updated— today's date - §3
version_last_used— current saas-dev version - §9 Recent Changes — prepend one entry:
| YYYY-MM-DD | [SKILL_NAME] | [VERSION] | [change] |
Update as relevant to work done:
- §4 Dependency Registry — new packages added (version + one-line purpose)
- §5 Environment Variables — new env vars (under correct subsection)
- §6 Third-Party Integrations — new row if integration added
- §7 Architecture Decisions — new ADR for non-obvious design choices
- §8 Known Issues — append if discovered during work
Emit update checkpoint to chat:
✓ CLAUDE.md updated:
§4: +N dependencies
§5: +N env vars
§7: +ADR-NNN (title)
§9: +1 change entry
Full format spec: saas-dev/references/router/claude-md-v2.md