Skip to main content
nextjs-dev Next.js 16 development patterns from Vercel's official Next.js Agent Skills (394 snippets). App Router, RSC boundaries, cache components, Turbopack, proxy.ts, Server Actions, metadata/SEO.
الانتقال إلى التثبيت سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/ktg-one/goodai-mate --skill nextjs-devيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... المزيد من هذا المستودع Good'ai brutalist/direct-mail frontend: brand tokens, stamp UI, voice hero, asset registry, and ESLint gates. Use when building or reviewing UI in goodai-mate, fixing design fidelity, prepping demos (ABS), running lint, or when the user says /goodai-frontend, goodai frontend, brutalist mail board, stamp design, or frontend-design for this project.
API Route Handler, Server Action, and data mutation patterns for Next.js 16. Zod validation, error handling, auth patterns, cache revalidation.
React 19 + Server Component patterns from official Vercel/React docs. Component templates, hooks patterns, RSC boundaries, performance optimization.
المهن ذات الصلة SOC
استنادا إلى تصنيف SOC المهني
name nextjs-dev description Next.js 16 development patterns from Vercel's official Next.js Agent Skills (394 snippets). App Router, RSC boundaries, cache components, Turbopack, proxy.ts, Server Actions, metadata/SEO. user-invocable false
Next.js 16 Development Patterns (Official Vercel Source)
Based on /vercel-labs/next-skills — the official Vercel-maintained skill pack for Next.js agents.
File Conventions (App Router)
File Purpose Scope page.tsxUI unique to a route Route segment layout.tsxShared UI wrapping children Route segment + children loading.tsxInstant loading UI (Suspense) Route segment error.tsxError boundary ('use client' required) Route segment not-found.tsx404 UI Route segment route.tsAPI route handler Route segment template.tsxRe-rendered layout (no state persistence) Route segment default.tsxParallel route fallback
global-error.tsxRoot error boundary App-wide
proxy.tsRequest rewriting/routing (replaces middleware in v16) Project root
Route Groups src/app/
(marketing)/ # force-static — landing, blog, docs
(app)/ # force-dynamic — dashboard, settings
(auth)/ # auth flows — login, register, callback
React Server Component (RSC) Boundaries
Decision Tree
Does it handle user interaction (clicks, forms, state)? → 'use client'
Does it only render data? → Server Component (default)
Does it need browser APIs (window, localStorage)? → 'use client'
Is it heavy (chart, editor, map)? → next/dynamic with ssr: false
Does it fetch data? → Server Component with async + direct DB/API call
Directives
'use server'
'use client'
'use cache'
Boundary Rules
Server Components can import Client Components ✅
Client Components CANNOT import Server Components ❌
Client Components CAN render Server Components as children ✅
'use client' marks the boundary — everything imported below is client
import ClientShell from './client-shell'
import ServerData from './server-data'
export default function Page ( ) {
return (
<ClientShell >
<ServerData /> {/* stays on server */}
</ClientShell >
)
}
Async Patterns (Next.js 16)
params and searchParams are Promises
export default async function Page ({
params,
}: {
params: Promise <{ slug: string }>
} ) {
const { slug } = await params
return <Article slug ={slug} />
}
export async function generateMetadata ({
params,
}: {
params: Promise <{ slug: string }>
} ) {
const { slug } = await params
return { title : `Article: ${slug} ` }
}
Parallel Data Fetching — ALWAYS for independent data
const [user, posts, comments] = await Promise .all ([
getUser (id),
getPosts (id),
getComments (id),
])
const user = await getUser (id)
const posts = await getPosts (id)
const comments = await getComments (id)
Suspense Streaming import { Suspense } from 'react'
export default function Dashboard ( ) {
return (
<div >
<h1 > Dashboard</h1 >
<Suspense fallback ={ <CardSkeleton /> }>
<RevenueChart /> {/* streams when ready */}
</Suspense >
<Suspense fallback ={ <TableSkeleton /> }>
<LatestInvoices /> {/* streams independently */}
</Suspense >
</div >
)
}
Cache Components (Next.js 16 PPR)
async function CachedProductList ( ) {
'use cache'
const products = await db.product .findMany ()
return <ProductGrid products ={products} />
}
import { cacheLife } from 'next/cache'
async function CachedStats ( ) {
'use cache'
cacheLife ('hours' )
const stats = await getStats ()
return <StatsDisplay stats ={stats} />
}
import { cacheTag } from 'next/cache'
async function CachedList ({ tag }: { tag: string } ) {
'use cache'
cacheTag (tag)
const items = await getItems ()
return <ItemList items ={items} />
}
Server Actions 'use server'
import { z } from 'zod'
import { revalidatePath, revalidateTag } from 'next/cache'
import { redirect } from 'next/navigation'
const CreateSchema = z.object ({
name : z.string ().min (1 ).max (100 ),
email : z.string ().email (),
})
export async function createUser (formData : FormData ) {
const parsed = CreateSchema .safeParse (Object .fromEntries (formData))
if (!parsed.success ) {
return { error : parsed.error .flatten () }
}
const session = await auth ()
if (!session) {
return { error : 'Unauthorized' }
}
const user = await db.user .create ({ data : parsed.data })
revalidatePath ('/users' )
redirect (`/users/${user.id} ` )
}
'use client'
import { useRouter } from 'next/navigation'
function UpdateButton ( ) {
const router = useRouter ()
async function handleUpdate ( ) {
await updateItem (id)
router.refresh ()
}
return <button onClick ={handleUpdate} > Update</button >
}
Data Fetching Patterns
async function ProductPage ({ params }: { params: Promise <{ id: string }> } ) {
const { id } = await params
const product = await getProduct (id)
return <ProductView product ={product} />
}
export const revalidate = 3600
async function BlogPage ( ) {
const posts = await getPosts ()
return <PostList posts ={posts} />
}
export async function generateStaticParams ( ) {
const posts = await getPosts ()
return posts.map ((post ) => ({ slug : post.slug }))
}
export const dynamic = 'force-dynamic'
Route Handlers
import { NextRequest , NextResponse } from 'next/server'
import { z } from 'zod'
const Schema = z.object ({
name : z.string ().min (1 ).max (100 ),
})
export async function POST (request : NextRequest ) {
try {
const body = await request.json ()
const parsed = Schema .safeParse (body)
if (!parsed.success ) {
return NextResponse .json (
{ error : 'Validation failed' , details : parsed.error .flatten () },
{ status : 400 }
)
}
const result = await createResource (parsed.data )
return NextResponse .json (result, { status : 201 })
} catch (error) {
console .error ('[API] POST /api/resource:' , error)
return NextResponse .json ({ error : 'Internal server error' }, { status : 500 })
}
}
proxy.ts (Replaces middleware.ts in Next.js 16)
import type { NextRequest } from 'next/server'
export function proxy (request : NextRequest ) {
const { pathname } = request.nextUrl
if (pathname.startsWith ('/blog' )) {
return { rewrite : new URL ('/marketing/blog' + pathname.slice (5 ), request.url ) }
}
if (pathname.startsWith ('/dashboard' ) && !request.cookies .get ('session' )) {
return { redirect : new URL ('/login' , request.url ) }
}
}
Metadata / SEO
export const metadata = {
title : 'My App' ,
description : 'App description' ,
openGraph : {
title : 'My App' ,
description : 'App description' ,
images : ['/og.png' ],
},
}
export async function generateMetadata ({ params }: { params: Promise <{ slug: string }> } ) {
const { slug } = await params
const post = await getPost (slug)
return {
title : post.title ,
description : post.excerpt ,
openGraph : { images : [post.coverImage ] },
}
}
import { ImageResponse } from 'next/og'
export async function GET (request : NextRequest ) {
const { searchParams } = new URL (request.url )
const title = searchParams.get ('title' ) ?? 'Default Title'
return new ImageResponse (
<div style ={{ fontSize: 48 , background: 'white ', width: '100 %', height: '100 %', display: 'flex ', alignItems: 'center ', justifyContent: 'center ' }}>
{title}
</div > ,
{ width : 1200 , height : 630 }
)
}
Parallel & Intercepting Routes
export default function Layout ({
children,
analytics,
team,
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
} ) {
return (
<div >
{children}
{analytics}
{team}
</div >
)
}
Import Rules (Critical for Bundle Size)
import { Button , Card , Input } from '@/components/ui'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import HeavyChart from '@/components/heavy-chart'
import dynamic from 'next/dynamic'
const HeavyChart = dynamic (() => import ('@/components/heavy-chart' ), {
ssr : false ,
loading : () => <ChartSkeleton /> ,
})
Turbopack (Default in Next.js 16)
Turbopack is the default bundler for both next dev and next build
No webpack configuration needed for standard use cases
Built-in CSS, PostCSS, and Tailwind CSS support
Filesystem caching enabled by default
const config = {
experimental : {
turbo : {
},
},
}
Environment Variables
NEXT_PUBLIC_* — exposed to client bundle (public values only)
Everything else — server-only (API keys, secrets, DB URLs)
Never import process.env in client components without NEXT_PUBLIC_ prefix
Use src/types/env.d.ts for typed environment variables
Error Handling
'use client'
export default function Error ({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
} ) {
return (
<div >
<h2 > Something went wrong</h2 >
<p > {error.message}</p >
<button onClick ={reset} > Try again</button >
</div >
)
}
'use client'
export default function GlobalError ({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
} ) {
return (
<html >
<body >
<h2 > Something went wrong</h2 >
<button onClick ={reset} > Try again</button >
</body >
</html >
)
}