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

Read pinned source

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.

Files and excerpt

File metadata and permitted, redacted excerpts come from the recorded scan. Source links are pinned to that commit.

Browse files
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.