Next.js & Web
Use when creating or restructuring anything under a Next.js app/ directory: adding a route, page, or layout, deciding whether a component is a Server or Client Component, adding "use client", writing a route handler, setting metadata, or moving data fetching. Also use when a build complains that a hook or event handler cannot be used in a Server Component, or when data is fetched in the wrong place. If a file lands under app/, use this skill.
1 file
Description
Use when creating or restructuring anything under a Next.js app/ directory: adding a route, page, or layout, deciding whether a component is a Server or Client Component, adding "use client", writing a route handler, setting metadata, or moving data fetching. Also use when a build complains that a hook or event handler cannot be used in a Server Component, or when data is fetched in the wrong place. If a file lands under app/, use this skill.
Any work under an app/ directory: adding a route, splitting a component into client and server halves, wiring metadata, or debugging why a page is a client bundle when it should be static.
app/ is a Server Component by default. Add "use client" only on the leaf that needs state, effects, or browser APIs. Pushing "use client" up to a page turns the whole subtree into a client bundle.page.tsx. Shared shell is layout.tsx. Loading UI is loading.tsx. Error UI is error.tsx and must be a client component.Create app/thing/[slug]/page.tsx as a server component.
Export generateStaticParams returning every slug so the route is statically generated:
export async function generateStaticParams() {
const items = await getAllItems();
return items.map((i) => ({ slug: i.slug }));
}
Export generateMetadata for a per-page title, description, and canonical:
export async function generateMetadata({ params }): Promise<Metadata> {
const { slug } = await params;
const item = await getItem(slug);
return {
title: item.title,
description: item.excerpt,
alternates: { canonical: \`/thing/\${slug}\` },
};
}
Return notFound() from next/navigation for unknown slugs so you get a real 404, not a soft empty page.
params and searchParams are Promises. Await them. A synchronous params.slug read compiles but is undefined at runtime.export const metadata and generateMetadata cannot both live in the same file. Pick one."use client" file leaks it into the browser bundle. Guard server modules with import "server-only".Added 2026-07-01. Back to the Skill Library.

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.