/nextjs-mastery
Next.js 14+ App Router patterns including RSC, ISR, middleware, parallel routes, and data fetching
$ npx -y skills add rohitg00/awesome-claude-code-toolkit --skill nextjs-mastery --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/nextjs-mastery
Context preview
The summary Claude sees to decide when to auto-load this skill.
Next.js 14+ App Router patterns including RSC, ISR, middleware, parallel routes, and data fetching
SKILL.md
nextjs-mastery.SKILL.mdname: nextjs-mastery
description: Next.js 14+ App Router patterns including RSC, ISR, middleware, parallel routes, and data fetching
Next.js Mastery
App Router Structure
app/
layout.tsx # Root layout (wraps all pages)
page.tsx # Home route /
loading.tsx # Route-level Suspense fallback
error.tsx # Route-level error boundary
not-found.tsx # Custom 404
(marketing)/
about/page.tsx # /about (grouped without URL segment)
dashboard/
layout.tsx # Nested layout for /dashboard/*
page.tsx # /dashboard
@analytics/page.tsx # Parallel route slot
@activity/page.tsx # Parallel route slot
settings/
page.tsx # /dashboard/settings
api/
webhooks/route.ts # Route handler (POST /api/webhooks)Route groups `(name)` organize code without affecting URLs. Parallel routes `@slot` render multiple pages simultaneously.
Server Components and Data Fetching
async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const product = await db.product.findUnique({ where: { id } });
if (!product) notFound();
return (
<div>
<h1>{product.name}</h1>
<p>{product.description}</p>
<Suspense fallback={<ReviewsSkeleton />}>
<Reviews productId={id} />
</Suspense>
</div>
);
}
async function Reviews({ productId }: { productId: string }) {
const reviews = await db.review.findMany({ where: { productId } });
return (
<ul>
{reviews.map(r => <li key={r.id}>{r.text} - {r.rating}/5</li>)}
</ul>
);
}Server Components are the default. They run on the server, can access databases directly, and send zero JavaScript to the client.
ISR and Caching
export const revalidate = 3600;
async function BlogPage() {
const posts = await fetch("https://api.example.com/posts", {
next: { revalidate: 3600, tags: ["posts"] },
}).then(r => r.json());
return <PostList posts={posts} />;
}import { revalidateTag, revalidatePath } from "next/cache";
export async function createPost(formData: FormData) {
"use server";
await db.post.create({ data: { title: formData.get("title") as string } });
revalidateTag("posts");
revalidatePath("/blog");
}Middleware
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("session")?.value;
if (request.nextUrl.pathname.startsWith("/dashboard") && !token) {
return NextResponse.redirect(new URL("/login", request.url));
}
const response = NextResponse.next();
response.headers.set("x-request-id", crypto.randomUUID());
return response;
}
export const config = {
matcher: ["/dashboard/:path*", "/api/:path*"],
};Middleware runs at the edge before every matched request. Keep it lightweight.
Server Actions
"use server";
import { z } from "zod";
import { revalidatePath } from "next/cache";
const schema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
});
export async function updateProfile(prevState: any, formData: FormData) {
const parsed = schema.safeParse(Object.fromEntries(formData));
if (!parsed.success) {
return { errors: parsed.error.flatten().fieldErrors };
}
await db.user.update({
where: { email: parsed.data.email },
data: { name: parsed.data.name },
});
revalidatePath("/profile");
return { success: true };
}Anti-Patterns
- Adding `'use client'` to top-level layout or page components
- Fetching data on the client when it can be done in a Server Component
- Using `useEffect` for data fetching instead of Server Components or `use()`
- Not wrapping slow async components with `<Suspense>`
- Putting heavy logic in middleware (it runs on every matched request)
- Ignoring `loading.tsx` and `error.tsx` conventions
Checklist
- [ ] Server Components used by default; `'use client'` only on interactive leaves
- [ ] Data fetching happens in Server Components with proper caching
- [ ] `<Suspense>` boundaries wrap independent async sections
- [ ] `loading.tsx` and `error.tsx` exist for key routes
- [ ] Middleware is lightweight and only handles auth/redirects/headers
- [ ] Server Actions validate input with Zod before database writes
- [ ] `revalidateTag` or `revalidatePath` called after mutations
- [ ] Route groups and parallel routes used to organize complex layouts
Read more
name: nextjs-mastery description: Next.js 14+ App Router patterns including RSC, ISR, middleware, parallel routes, and data fetching
Next.js Mastery
App Router Structure
app/
layout.tsx # Root layout (wraps all pages)
page.tsx # Home route /
loading.tsx # Route-level Suspense fallback
error.tsx # Route-level error boundary
not-found.tsx # Custom 404
(marketing)/
about/page.tsx # /about (grouped without URL segment)
dashboard/
layout.tsx # Nested layout for /dashboard/*
page.tsx # /dashboard
@analytics/page.tsx # Parallel route slot
@activity/page.tsx # Parallel route slot
settings/
page.tsx # /dashboard/settings
api/
webhooks/route.ts # Route handler (POST /api/webhooks)Route groups `(name)` organize code without affecting URLs. Parallel routes `@slot` render multiple pages simultaneously.
Server Components and Data Fetching
async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const product = await db.product.findUnique({ where: { id } });
if (!product) notFound();
return (
<div>
<h1>{product.name}</h1>
<p>{product.description}</p>
<Suspense fallback={<ReviewsSkeleton />}>
<Reviews productId={id} />
</Suspense>
</div>
);
}
async function Reviews({ productId }: { productId: string }) {
const reviews = await db.review.findMany({ where: { productId } });
return (
<ul>
{reviews.map(r => <li key={r.id}>{r.text} - {r.rating}/5</li>)}
</ul>
);
}Server Components are the default. They run on the server, can access databases directly, and send zero JavaScript to the client.
ISR and Caching
export const revalidate = 3600;
async function BlogPage() {
const posts = await fetch("https://api.example.com/posts", {
next: { revalidate: 3600, tags: ["posts"] },
}).then(r => r.json());
return <PostList posts={posts} />;
}import { revalidateTag, revalidatePath } from "next/cache";
export async function createPost(formData: FormData) {
"use server";
await db.post.create({ data: { title: formData.get("title") as string } });
revalidateTag("posts");
revalidatePath("/blog");
}Middleware
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("session")?.value;
if (request.nextUrl.pathname.startsWith("/dashboard") && !token) {
return NextResponse.redirect(new URL("/login", request.url));
}
const response = NextResponse.next();
response.headers.set("x-request-id", crypto.randomUUID());
return response;
}
export const config = {
matcher: ["/dashboard/:path*", "/api/:path*"],
};Middleware runs at the edge before every matched request. Keep it lightweight.
Server Actions
"use server";
import { z } from "zod";
import { revalidatePath } from "next/cache";
const schema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
});
export async function updateProfile(prevState: any, formData: FormData) {
const parsed = schema.safeParse(Object.fromEntries(formData));
if (!parsed.success) {
return { errors: parsed.error.flatten().fieldErrors };
}
await db.user.update({
where: { email: parsed.data.email },
data: { name: parsed.data.name },
});
revalidatePath("/profile");
return { success: true };
}Anti-Patterns
- Adding `'use client'` to top-level layout or page components
- Fetching data on the client when it can be done in a Server Component
- Using `useEffect` for data fetching instead of Server Components or `use()`
- Not wrapping slow async components with `<Suspense>`
- Putting heavy logic in middleware (it runs on every matched request)
- Ignoring `loading.tsx` and `error.tsx` conventions
Checklist
- [ ] Server Components used by default; `'use client'` only on interactive leaves
- [ ] Data fetching happens in Server Components with proper caching
- [ ] `<Suspense>` boundaries wrap independent async sections
- [ ] `loading.tsx` and `error.tsx` exist for key routes
- [ ] Middleware is lightweight and only handles auth/redirects/headers
- [ ] Server Actions validate input with Zod before database writes
- [ ] `revalidateTag` or `revalidatePath` called after mutations
- [ ] Route groups and parallel routes used to organize complex layouts
The most comprehensive toolkit for Claude Code -- 135 agents, 35 curated skills (+400,000 via SkillKit), 42 commands, 176+ plugins, 20 hooks, 15 rules, 7 templates, 15 MCP configs, 26 companion apps, 53 ecosystem entries, and more.
Repo: rohitg00/awesome-claude-code-toolkit
Other skills on rohitg00-claude-code-toolkit.
- /accessibility-wcag
Web accessibility patterns for WCAG 2.2 compliance including ARIA, keyboard navigation, screen readers, and testing
Open skill - /agentkit-seo
Route broad or ambiguous AgentKit SEO work to the right module while keeping context scoped. Use when a request spans multiple surfaces, asks for overall digital-presence strategy, involves provider or install architecture, needs agent-context planning, or the correct platform
Open skill - /api-design-patterns
REST API design with resource naming, pagination, versioning, and OpenAPI spec generation
Open skill - /authentication-patterns
Authentication and authorization patterns including OAuth2, JWT, RBAC, session management, and PKCE flows
Open skill - /aws-cloud-patterns
AWS cloud patterns for Lambda, ECS, S3, DynamoDB, and Infrastructure as Code with CDK/Terraform
Open skill - /ci-cd-pipelines
CI/CD pipeline patterns for GitHub Actions, GitLab CI, testing strategies, and deployment automation
Open skill

