May 2026 · Workflow · ~10 min read
The Production-Ready .cursorrules Template for Next.js App Router Teams
By Safdar Ali — frontend engineer, Bengaluru
My Cursor + Claude workflow post covers how I prompt and review. This one is what the model sees before every Agent run: the context file. Most teams write rules that make AI generate components faster. Fewer write rules that block env leaks, wrong client boundaries, or TypeScript shortcuts that fail CI.
I keep this in .cursor/rules/nextjs-app-router.mdc (Cursor's current format) on every Next.js 15 repo. Copy it, trim project-specific paths, commit it. Agentic coding only scales when non-functional requirements are as explicit as "use Tailwind."
Why most context files fail in production
- They describe stack ("we use Next.js") but not boundaries (Server vs Client)
- No rule against
process.env.SECRETin client files - No instruction to run
npm run buildbefore declaring done - Generic "write clean code" — models ignore it under time pressure
- Missing reference files — Agent invents a new folder layout every ticket
Research on AI context files matches what I see in review: functional rules get followed; security and performance rules get skipped unless they are concrete and testable.
The full template (copy-paste)
Below is my literal file — ~120 lines. Replace REFERENCE_LAYOUT=app/blog/rsc-vs-client-components/page.tsx with your best article or page component.
---
description: Next.js 15 App Router production rules for Agent and Chat
globs: app/**/*.{tsx,ts,jsx,js}, components/**/*, lib/**/*
alwaysApply: true
---
# Role
You are a senior frontend engineer on a Next.js 15 + React 19 + TypeScript (strict) codebase.
Optimize for: correct RSC boundaries, minimal client JS, accessibility, SEO metadata, and passing `npm run build`.
# Stack (do not substitute)
- Next.js App Router only — no Pages Router patterns
- TypeScript strict — no `any`, no `@ts-ignore` without comment
- Tailwind for styling — match existing class patterns
- Data: Server Components + fetch/cache tags OR Server Actions — no new REST routes unless asked
# Server vs Client (mandatory)
- Default: Server Component — no "use client" unless interactivity, browser APIs, or hooks required
- Never import server-only modules into client components (db, fs, raw env secrets)
- Never put "use client" on layouts that only wrap children unless required
- Split: server shell fetches data; client island is the smallest interactive leaf
- Reference pattern: app/blog/rsc-vs-client-components/page.tsx (structure, metadata, prose classes)
# Streaming & Suspense
- Wrap slow server fetches in <Suspense> with skeleton matching final layout dimensions (prevent CLS)
- Do not await unrelated data serially in one page — parallelize with Promise.all
- loading.tsx must mirror final layout geometry
# Environment & secrets
- Client code: only NEXT_PUBLIC_* env vars
- Never log or stringify process.env in client bundles
- Server secrets only in Server Components, Route Handlers, or Server Actions marked "use server"
- If unsure whether a var is public, treat as server-only
# TypeScript
- Props: explicit interfaces, export types from colocated types.ts when shared
- Server Actions: Zod (or existing validator) at top of action — return typed ActionResult
- Prefer `satisfies` over assertions
# SEO & metadata
- Every new route: export metadata or generateMetadata with title, description, canonical
- One h1 per page; heading hierarchy must not skip levels
- Images: next/image with width/height or fill + sizes
# Performance (non-optional)
- No barrel imports that pull entire libraries into client bundles
- dynamic() for heavy client charts/editors with ssr: false inside reserved-height containers
- Before removing useMemo/useCallback: note "verify in React Profiler — Compiler may not cover module refs"
# Security
- No dangerouslySetInnerHTML without explicit approval in ticket
- Sanitize user HTML if required
- Server Actions: validate auth inside action, not only in UI
# Agent workflow
1. Analyze pass: list files to touch, risks, RSC boundary plan — no edits
2. Implement pass: minimal diff, match conventions, no drive-by refactors
3. Run: npm run build — fix all errors before finishing
4. Summarize: what changed, what to manually test (mobile, dark mode, SEO)
# Forbidden without explicit ask
- New state management libraries
- Converting Server Components to client "for simplicity"
- Adding API routes when Server Actions suffice
- Changing tailwind.config, next.config, or CI files
# Project paths (customize)
- Blog pattern: app/blog/[slug]/page.tsx
- UI classes: lib/ui-classes.js
- Data: data/*.js — keep fetch logic out of client componentsClaude / Cursor custom instructions
For cursor ai claudecustom prompt configuration, I mirror the same bullets in Cursor Settings → Rules for AI (user-level) but keep repo-specific paths only in .cursor/rules. User rules say "always respect project .cursor/rules"; project rules say "reference rsc-vs-client-components page." That split stops personal preferences from leaking into client repos.
Agent mode prompt I prepend
Follow .cursor/rules/nextjs-app-router.mdc exactly.
Task: [one paragraph scope]
Done when: build passes, no new client boundaries without justification, dark mode unchanged.Rule in action: forcing RSC boundaries
Without rules, Agent often produces this:
"use client";
import { getPosts } from "@/lib/db";
export default function BlogPage() {
const [posts, setPosts] = useState([]);
useEffect(() => { getPosts().then(setPosts); }, []);
// ...
}With rules + reference file, the same ticket yields server fetch + client filter island — matching how I document RSC splits.
Rule in action: blocking env leaks
I caught Agent adding console.log(process.env) in a client hook for debugging. The rule line "Never log process.env in client bundles" plus globs on components/** reduced repeats. For how to configure cursor for typescript, the strict-mode bullets matter more than model choice — Sonnet still emits any without guardrails.
TypeScript enforcement snippet
Add to rules if your team uses Server Actions heavily:
# Server Actions shape
type ActionResult<T> =
| { ok: true; data: T }
| { ok: false; error: string };
Every action returns ActionResult — never throw to client for validation errors.Agentic coding workflows that respect rules
- Ticket → analyze-only Agent — outputs file list + boundary diagram in comments
- Implement Agent — must cite which rule applied for each new
"use client" - Human review — check env, metadata, CLS skeletons (rules mention them; humans verify)
- Build in CI — rules are worthless if merge does not require green build
Compare tools: GitHub Copilot vs Cursor. Broader AI coding context: how AI changed React coding.
Closing
The best cursorrules for nextjs are boring: explicit Server/Client law, env boundaries, build gate, reference files. Agentic coding workflows only beat copy-paste when the model cannot pretend performance and security are optional. Drop this file in your repo today; tighten paths tomorrow.
If this helped you
I publish free tutorials and write-ups like this in my spare time — no paywall on the guides. If it saved you an afternoon of trial and error, you can support the work:
- Buy me a coffee at buymeacoffee.com/safdarali
- Subscribe to my YouTube channel — it's free; 70+ React & Next.js tutorials
Related reading
More guides on safdarali.in — same author, production-focused.
- Workflow
How I Use Cursor + Claude to Ship React Code 3x Faster
Not generic AI hype — Safdar Ali's Cursor AI React workflow: Agent mode, production review checklist, and how I ship Next.js 3× faster without slop.
May 2026Read article →
- FrameSnap
Free Video Thumbnail Generator Online — No Upload
Free video thumbnail generator online — extract frames from video without upload. Browser-based, no watermark, YouTube thumbnail from MP4 workflow.
Jun 2026Read article →