From coding-agent
Next.js specialist knowledge — App Router architecture, Server Components, Server Actions, rendering strategies, caching, routing, API route handlers, and optimization patterns for Next.js 14+.
npx claudepluginhub devjarus/coding-agentThis skill uses the workspace's default tool permissions.
Deep expertise in Next.js 14+ App Router, Server Components, Server Actions, rendering strategies, and full-stack data patterns.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Deep expertise in Next.js 14+ App Router, Server Components, Server Actions, rendering strategies, and full-stack data patterns.
page.tsx, layout.tsx, loading.tsx, error.tsx, route.ts'use client' only for browser APIs/state/effectsrevalidatePath()/revalidateTag()unstable_cache, React cache(), tag-based invalidation<Link>, useRouter(), middleware, dynamic segmentsnext/image, next/font, <Script>, metadata exportNEXT_PUBLIC_ for client, plain for server-onlyPromise.all() for independent concurrent fetches in Server Componentserror.tsx at every route segment with independent failure modesloading.tsx at segments whose data takes perceptibly longpage.tsx must export metadata or generateMetadataThese bite real projects and produce runtime errors, not typecheck errors — easy to miss in smoke tests. Always navigate actual routes in the evaluator's runtime verification, not just curl /.
In Next.js 15+, dynamic segment params and searchParams are Promises. Must await them before use in both page.tsx and route.ts:
// app/notes/[...slug]/page.tsx
export default async function NotePage({ params }: { params: Promise<{ slug: string[] }> }) {
const { slug } = await params; // REQUIRED: await first
const path = slug.join("/");
// ...
}
// app/api/notes/[...slug]/route.ts
export async function GET(
req: Request,
{ params }: { params: Promise<{ slug: string[] }> }
) {
const { slug } = await params; // REQUIRED: await first
// ...
}
Forgetting the await produces cryptic runtime errors like Cannot read properties of undefined (reading 'join'), NOT typecheck errors.
dynamic(() => ..., { ssr: false }) cannot be called from server componentsIn Next.js 15, next/dynamic with ssr: false is forbidden inside server components. The working pattern: a tiny client-component wrapper whose only job is to host the dynamic() call:
// app/components/command-palette-loader.tsx
'use client';
import dynamic from 'next/dynamic';
const CommandPalette = dynamic(() => import('./command-palette'), { ssr: false });
export default function CommandPaletteLoader() {
return <CommandPalette />;
}
// app/layout.tsx (server component)
import CommandPaletteLoader from './components/command-palette-loader';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<CommandPaletteLoader />
{children}
</body>
</html>
);
}
The rest of the shell layout stays a server component. Only the loader is client.
next-themes injects an IIFE into <body> that reads localStorage (or prefers-color-scheme) and calls document.documentElement.classList.add('dark') before React hydrates. Without this script, there's a flash of light mode on first paint even when the user prefers dark.
Three things are required for this to work:
<html suppressHydrationWarning> on the root — the IIFE mutates classList before React runs, which would normally trigger a hydration warning<ThemeProvider> from next-themes wrapping the appcurl -s http://localhost:<port>/ | grep -c 'classList.add')Verify dark-mode-won't-flash by inspecting the served HTML, not just the React tree. Missing IIFE = FOUC on every first paint.
next dev silently falls back to port 3001 (or the next available) if 3000 is taken, and only logs it once in the initial output. Never hardcode 3000 in evaluator scripts — parse the actual port from stderr. Curling the wrong port will hit whatever other process owns 3000, which is almost always misleading.
pnpm dev wipes .next/ on restartIf you verify a specific compiled chunk (e.g., a code-split file 807.<hash>.js) and then start pnpm dev, the chunk filename changes and the file you verified no longer exists. Verify build artifacts BEFORE starting the dev server, not after. Applies equally to any framework with a dev pipeline (Vite, Astro, webpack-dev-server).
'use client' only when needed<img> tags