Individual skill
nextjs
Apply these opinionated Next.js conventions whenever writing or reviewing App Router code (14+): Server Components by default, where the 'use client' boundary belongs, the caching defaults that changed in Next 15, tag-based revalidation, treating Server Actions as public endpoints, the Metadata API, and next/image and next/font.
plugins/engineering/cortex-web/skills/nextjs/SKILL.md
Source commit 8e809de409ce0c6539f0e31e821196efc4d7c7c9
What was checked
- Matches the observed repository HEAD
- Yes
- Scanner rules are current
- Yes
- Repository scan complete
- No
- Skill scan complete
- Yes
- Observed behavior
- Instructions only
- Last checked
- Nov 5, 2026
These are observations at the recorded commit, not a guarantee of safety. Review the source before running it.
Install this skill
Choose an agent in your Stack or copy a command below. Commands fetch the pinned commit and copy only this skill directory. Existing destinations are refused. Copying a command does not install anything.
An install command is unavailable: current rules, complete repository and skill scans, an eligible behavior level and a permitted license are required.
Repository context
- Repository stars (not skill ratings)
- 18
- Repository last updated
- Oct 23, 2026
- License
- MIT
Observed agent integration: No specific integration evidence. Standard SKILL.md installation does not imply verified compatibility.
- ai-skill Repository topic
- ai-skills Repository topic
- claude-code Repository topic
- claude-code-skill Repository topic
- claude-code-skills Repository topic
- cursor Repository topic
- cursor-skill Repository topic
- cursor-skills Repository topic
- opencode-skill Repository topic
- opencode-skills Repository topic
- writing Derived category
- engineering Derived category
- engineering-web Derived category
Files and excerpt
File metadata and permitted, redacted excerpts come from the recorded scan. Source links are pinned to that commit.
Browse files
SKILL.mdcore · 3,218 bytes
Read excerpt
# Next.js
House conventions for Next.js App Router (14+). Apply them to code you are writing or changing — don't migrate untouched routes unless asked.
## Conventions
- **App Router only.** Never add to `pages/`. If a project still has one, new work goes in `app/` and the two coexist until someone schedules the migration.
- **Server Components by default.** `'use client'` marks a leaf that needs interactivity, not a page. Everything above that marker ships to the browser too, so the boundary belongs as deep in the tree as it will go.
- **Verify caching behaviour against the installed version — it changed.** Through Next 14, `fetch` was cached by default and you opted out; from Next 15, `fetch`, Route Handlers, and client navigation are uncached by default and you opt in. Assuming the wrong default gives you either stale pages or an origin taking every request. Check `package.json`, then set the intent explicitly (`cache`, `next.revalidate`, or route segment config) rather than relying on whatever the default happens to be.
- **`params` and `searchParams` are Promises from Next 15 on** — `const { slug } = await params`. Code written against 14 destructures them synchronously and breaks on upgrade, so check the installed major before copying either form.
- **A `layout.tsx` auth check is not a security boundary.** Layouts don't re-render on every navigation between their child routes, so the check can be skipped on client-side transitions. Enforce access in middleware and again where the data is read; the layout check is UX, not enforcement.
- **Tag what you fetch, revalidate by tag.** `next: { tags: ['user'] }` plus `revalidateTag('user')` after a mutation invalidates exactly the affected data. Time-based revalidation is a guess about staleness; tags are a fact about it.
- **Server Actions are public endpoints.** They are reachable by anyone who can find the action ID, so every one re-checks auth and re-validates its input server-side. The form it was rendered behind proves nothing about the caller.
- **Fetch in the component that renders the data.** React dedupes identical requests within a render pass, so prop-drilling data down to avoid a "duplicate" fetch buys nothing and couples the tree.