
Nextjs App Router
Structure Next.js App Router pages with correct Server vs Client boundaries and hybrid data-fetch patterns.
Overview
nextjs-app-router is an agent skill most often used in Build (also Ship) that teaches Server Component defaults, Client Component boundaries, and hybrid composition in the Next.js App Router.
Install
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill nextjs-app-routerWhat is this skill?
- Server Components as default with async data fetch and env-backed APIs
- Client Components gated by "use client" for hooks, events, and browser APIs
- Hybrid pattern: server pages fetch data and compose smaller client child components
- Examples cover product listings and sensitive server-side data access
- Reduces client bundle by keeping heavy logic on the server
Adoption & trust: 1.1k installs on skills.sh; 271 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are starting or refactoring a Next.js app and the agent keeps mixing Pages Router patterns, client-only fetch, or hooks in server files.
Who is it for?
Solo builders shipping Next.js 13+ apps who want consistent RSC guidance in every codegen session.
Skip if: Teams staying on Pages Router only, or projects that need a full design system or deployment runbook instead of routing fundamentals.
When should I use this skill?
When implementing or reviewing Next.js App Router pages, layouts, and component boundaries.
What do I get? / Deliverables
After the skill runs, pages follow App Router defaults with clear server/client splits and copy-paste patterns for async server data plus interactive client islands.
- Server Component page patterns
- Client Component islands
- Hybrid composition examples
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
App Router architecture decisions belong on the build shelf where solo builders lay out routes, components, and data loading. Teaches page.tsx patterns, RSC defaults, and client islands—core frontend work in the app directory.
Where it fits
Scaffold a products page that loads rows on the server and passes props into a client ProductCard.
Wire server-side fetch to an external API URL using environment variables without exposing keys to the browser.
Audit which widgets truly need client JavaScript before adding use client everywhere.
How it compares
Reference skill for App Router boundaries—not a substitute for a full component library or E2E test harness.
Common Questions / FAQ
Who is nextjs-app-router for?
Indie and solo developers using AI agents to build Next.js frontends who need correct Server and Client Component patterns without re-reading the docs each sprint.
When should I use nextjs-app-router?
During Build when creating app/ routes and Server Components; during Ship when reviewing bundle size and whether interactivity belongs on the client; anytime you validate that sensitive fetches stay on the server.
Is nextjs-app-router safe to install?
Review the Security Audits panel on this Prism page and the upstream SKILL.md before trusting automated edits to your repository.
SKILL.md
READMESKILL.md - Nextjs App Router
# Next.js App Router Fundamentals ## Server Components vs Client Components ### Server Components (Default) I Server Components sono il default in App Router. Eseguono sul server e possono: - Accedere direttamente a database, file system, API esterne - Renderizzare dati sensibili senza esporli al client - Ridurre il bundle JavaScript inviato al client ```tsx // app/page.tsx - Server Component di default async function getData() { const res = await fetch(`${process.env.API_URL}/data`); return res.json(); } export default async function Page() { const data = await getData(); return <main>{/* render data */}</main>; } ``` ### Client Components Usare `"use client"` per componenti che necessitano di: - React hooks (useState, useEffect, useContext) - Browser APIs (window, document, localStorage) - Event handlers (onClick, onSubmit) - Third-party librerie client-only ```tsx "use client"; import { useState } from "react"; export default function Counter() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> Count: {count} </button> ); } ``` ### Pattern Ibrido (Server + Client) ```tsx // app/page.tsx - Server Component import { ProductCard } from "./product-card"; async function getProducts() { return db.product.findMany(); } export default async function ProductsPage() { const products = await getProducts(); return ( <div> {products.map((product) => ( <ProductCard key={product.id} product={product} /> ))} </div> ); } ``` ```tsx // app/product-card.tsx - Client Component "use client"; import { useState } from "react"; export function ProductCard({ product }: { product: Product }) { const [isAdded, setIsAdded] = useState(false); return ( <div> <h3>{product.name}</h3> <button onClick={() => setIsAdded(true)}> {isAdded ? "Added!" : "Add to Cart"} </button> </div> ); } ``` ## React Compiler (Next.js 16+) Next.js 16 include React Compiler per memoizzazione automatica. ```ts // next.config.ts import type { NextConfig } from "next"; const nextConfig: NextConfig = { experimental: { reactCompiler: true, }, }; export default nextConfig; ``` Con React Compiler attivo, non serve più manualmente: - `React.memo()` (in molti casi) - `useMemo()` per computazioni semplici - `useCallback()` per event handlers semplici ## File Conventions Speciali ### loading.tsx Mostra UI durante il caricamento di dati. ```tsx // app/blog/loading.tsx export default function Loading() { return <p>Loading posts...</p>; } ``` ### error.tsx Gestisce errori nel segmento con Error Boundary. ```tsx // app/blog/error.tsx "use client"; export default function Error({ error, reset, }: { error: Error; reset: () => void; }) { return ( <div> <h2>Something went wrong!</h2> <button onClick={() => reset()}>Try again</button> </div> ); } ``` ### not-found.tsx Pagina 404 per segmento. ```tsx // app/blog/not-found.tsx export default function NotFound() { return ( <div> <h2>Not Found</h2> <p>Could not find requested resource</p> </div> ); } ``` ```tsx // Per triggerare programmaticamente import { notFound } from "next/navigation"; export default async function BlogPost({ params }: PageProps) { const post = await fetchPost((await params).slug); if (!post) { notFound(); } return <article>{/* ... */}</article>; } ``` ### template.tsx Simile a layout.tsx ma: - Si re-mounta su ogni navigazione - Mantiene stato/UI separati tra le route ```tsx // app/dashboard/template.tsx export default function Template({ children, }: { children: React.ReactNode; }) { return <div className="animate-fade-in">{children}</div>; } ``` ### default.tsx Fallback per parallel routes quando non c'è match. ```tsx // app/dashboard/@team/default.tsx export default function Default() { return <div>Select a team member</div>; } ``` ## Navigation ###