Token导航 LogoToken导航TokenDH.com
开发规范操作浏览器clawhub未标认证来源可访问clear审计通过

nextjs-guidelinesNext.js guidelines 开发

Agent Skill

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

总安装

29,961

周安装

1,236

GitHub Stars

公开资料未说明

下载量

9,789
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:nextjs-guidelines(Next.js guidelines 开发)
来源仓库:https://github.com/wpank/nextjs-guidelines
安装命令:
openclaw skills install nextjs-guidelines
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install nextjs-guidelines

简介

Next.js App Router 最佳实践 - Next.js 14-16+ 的服务器组件、数据获取、缓存、路由、中间件、元数据、错误处理、流式传输、服务器操作和性能优化。

SKILL.md

name
nextjs
model
standard
description
Next.js App Router best practices — Server Components, data fetching, caching, routing, middleware, metadata, error handling, streaming, Server Actions, and performance optimization for Next.js 14-16+.
keywords
[next.js, nextjs, app router, server components, rsc, server actions, streaming, suspense, parallel routes, intercepting routes, metadata, middleware, caching, revalidation, image optimization, font optimization]
user-invocable
false

Next.js App Router

Apply these patterns when building, reviewing, or debugging Next.js App Router applications.

Installation

OpenClaw / Moltbot / Clawbot

npx clawhub@latest install nextjs

WHEN

  • Building Next.js applications with App Router
  • Migrating from Pages Router to App Router
  • Implementing Server Components and streaming
  • Setting up parallel and intercepting routes
  • Optimizing data fetching and caching
  • Building full-stack features with Server Actions
  • Debugging hydration errors or RSC boundary issues

Rendering Modes

ModeWhereWhen to Use
Server ComponentsServer onlyData fetching, secrets, heavy computation
Client ComponentsBrowserInteractivity, hooks, browser APIs
Static (SSG)Build timeContent that rarely changes
Dynamic (SSR)Request timePersonalized or real-time data
StreamingProgressiveLarge pages, slow data sources

Server vs Client Decision Tree

Does it need...?
├── useState, useEffect, event handlers, browser APIs
│   └── Client Component ('use client')
├── Direct data fetching, no interactivity
│   └── Server Component (default)
└── Both?
    └── Split: Server parent fetches data → Client child handles UI

File Conventions

See file-conventions.md for complete reference.

app/
├── layout.tsx          # Shared UI wrapper (persists across navigations)
├── page.tsx            # Route UI
├── loading.tsx         # Suspense fallback (automatic)
├── error.tsx           # Error boundary (must be 'use client')
├── not-found.tsx       # 404 UI
├── route.ts            # API endpoint (cannot coexist with page.tsx)
├── template.tsx        # Like layout but re-mounts on navigation
├── default.tsx         # Parallel route fallback
└── opengraph-image.tsx # OG image generation

Route segments: [slug] dynamic, [...slug] catch-all, [[...slug]] optional catch-all, (group) route group, @slot parallel route, _folder private (excluded from routing).

Data Fetching Patterns

Choose the right pattern for each use case. See data-patterns.md for full decision tree.

PatternUse CaseCaching
Server Component fetchInternal reads (preferred)Full Next.js caching
Server ActionMutations, form submissionsPOST only, no cache
Route HandlerExternal APIs, webhooks, public RESTGET can be cached
Client fetch → APIClient-side reads (last resort)HTTP cache headers

Server Component Data Fetching (Preferred)

// app/products/page.tsx — Server Component by default
export default async function ProductsPage() {
  const products = await db.product.findMany() // Direct DB access, no API layer
  return <ProductGrid products={products} />
}

Avoiding Data Waterfalls

// BAD: Sequential — each awaits before the next starts
const user = await getUser()
const posts = await getPosts()

// GOOD: Parallel fetching
const [user, posts] = await Promise.all([getUser(), getPosts()])

// GOOD: Streaming with Suspense — each section loads independently
<Suspense fallback={<UserSkeleton />}><UserSection /></Suspense>
<Suspense fallback={<PostsSkeleton />}><PostsSection /></Suspense>

Server Actions (Mutations)

// app/actions.ts
'use server'
import { revalidateTag } from 'next/cache'

export async function addToCart(productId: string) {
  const cookieStore = await cookies()
  const sessionId = cookieStore.get('session')?.value
  if (!sessionId) redirect('/login')

  await db.cart.upsert({
    where: { sessionId_productId: { sessionId, productId } },
    update: { quantity: { increment: 1 } },
    create: { sessionId, productId, quantity: 1 },
  })
  revalidateTag('cart')
  return { success: true }
}

Caching Strategy

MethodSyntaxUse Case
No cachefetch(url, { cache: 'no-store' })Always-fresh data
Staticfetch(url, { cache: 'force-cache' })Rarely changes
ISRfetch(url, { next: { revalidate: 60 } })Time-based refresh
Tag-basedfetch(url, { next: { tags: ['products'] } })On-demand invalidation

Invalidate from Server Actions:

'use server'
import { revalidateTag, revalidatePath } from 'next/cache'

export async function updateProduct(id: string, data: ProductData) {
  await db.product.update({ where: { id }, data })
  revalidateTag('products')   // Invalidate by tag
  revalidatePath('/products') // Invalidate by path
}

RSC Boundaries

Props crossing Server → Client boundary must be JSON-serializable. See rsc-boundaries.md.

Prop TypeValid?Fix
string, number, booleanYes
Plain object / arrayYes
Server Action ('use server')Yes
Function () => {}NoDefine inside client component
Date objectNoUse .toISOString()
Map, Set, class instanceNoConvert to plain object/array

Critical rule: Client Components cannot be async. Fetch data in a Server Component parent and pass it down.

Async APIs (Next.js 15+)

params, searchParams, cookies(), and headers() are all async. See async-patterns.md.

// Pages and layouts — always await params
type Props = { params: Promise<{ slug: string }> }

export default async function Page({ params }: Props) {
  const { slug } = await params
}

// Server functions
const cookieStore = await cookies()
const headersList = await headers()

// Non-async components — use React.use()
import { use } from 'react'
export default function Page({ params }: Props) {
  const { slug } = use(params)
}

Routing Patterns

Route Organization

PatternSyntaxPurpose
Route groups(marketing)/Organize without affecting URL
Parallel routes@analytics/Multiple independent sections in one layout
Intercepting routes(.)photos/[id]Modal overlays on soft navigation
Private folders_components/Exclude from routing

Parallel Routes & Modals

See parallel-routes.md for complete modal pattern.

Key rules:

  • Every @slot folder must have a default.tsx (returns null) or you get 404 on refresh
  • Close modals with router.back(), never router.push() or <Link>
  • Intercepting route matchers: (.) same level, (..) one level up, (...) from root

Metadata & SEO

See metadata.md for OG images, sitemaps, and file conventions.

// Static metadata (layout or page)
export const metadata: Metadata = {
  title: { default: 'My App', template: '%s | My App' },
  description: 'Built with Next.js',
}

// Dynamic metadata
export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params
  const post = await getPost(slug)
  return {
    title: post.title,
    description: post.description,
    openGraph: { images: [{ url: post.image, width: 1200, height: 630 }] },
  }
}

Metadata is Server Components only. If a page has 'use client', extract metadata to a parent layout.

Error Handling

See error-handling.md for full patterns including auth errors.

// app/blog/error.tsx — must be 'use client'
'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>
  )
}

Critical gotcha: redirect(), notFound(), forbidden(), and unauthorized() throw special errors. Never catch them in try/catch:

// BAD: redirect throw is caught — navigation fails!
try {
  await db.post.create({ data })
  redirect(`/posts/${post.id}`)
} catch (error) {
  return { error: 'Failed' } // Catches the redirect too!
}

// GOOD: Call redirect outside try-catch
let post
try { post = await db.post.create({ data }) }
catch (error) { return { error: 'Failed' } }
redirect(`/posts/${post.id}`)

Streaming with Suspense

export default async function ProductPage({ params }: Props) {
  const { id } = await params
  const product = await getProduct(id) // Blocking — loads first

  return (
    <div>
      <ProductHeader product={product} />
      <Suspense fallback={<ReviewsSkeleton />}>
        <Reviews productId={id} />       {/* Streams in independently */}
      </Suspense>
      <Suspense fallback={<RecommendationsSkeleton />}>
        <Recommendations productId={id} /> {/* Streams in independently */}
      </Suspense>
    </div>
  )
}

Hooks That Require Suspense Boundaries

HookSuspense Required
useSearchParams()Always (or entire page becomes CSR)
usePathname()In dynamic routes
useParams()No
useRouter()No

Performance

  • Always use next/image over <img> — see image-optimization.md
  • Always use next/link over <a> — client-side navigation with prefetching
  • Always use next/font — see font-optimization.md
  • Always use next/script — see scripts.md
  • Set priority on above-the-fold images (LCP)
  • Add sizes when using fill — without it, the largest image variant downloads
  • Dynamic imports for heavy client components: const Chart = dynamic(() => import('./Chart'))
  • Use generateStaticParams to pre-render dynamic routes at build time

Route Handlers

See route-handlers.md for API endpoint patterns.

Bundling

See bundling.md for fixing third-party package issues, server-incompatible packages, and ESM/CommonJS problems.

Hydration Errors

See hydration-errors.md for all causes and fixes.

CauseFix
Browser APIs (window, localStorage)Client component with useEffect mount check
new Date().toLocaleString()Render on client with useEffect
Math.random() for IDsUse useId() hook
<p><div>...</div></p>Fix invalid HTML nesting
Third-party scripts modifying DOMUse next/script with afterInteractive

Self-Hosting

See self-hosting.md for Docker, PM2, cache handlers, and deployment checklist.

Key points:

  • Use output: 'standalone' for Docker — creates minimal production bundle
  • Copy public/ and .next/static/ separately (not included in standalone)
  • Set HOSTNAME="0.0.0.0" for containers
  • Multi-instance ISR requires a custom cache handler (Redis/S3) — filesystem cache breaks
  • Set health check endpoint at /api/health

NEVER Do

NeverWhyInstead
Add 'use client' by defaultBloats client bundle, loses Server Component benefitsServer Components are default — add 'use client' only for interactivity
Make client components asyncNot supported — will crashFetch in Server Component parent, pass data as props
Pass Date/Map/functions to clientNot serializable across RSC boundarySerialize to string/plain object, or use Server Actions
Fetch from own API in Server ComponentsUnnecessary round-trip — you're already on the serverAccess DB/service directly
Wrap redirect()/notFound() in try-catchThey throw special errors that get swallowedCall outside try-catch or use unstable_rethrow()
Skip loading.tsx or Suspense fallbacksUsers see blank page during data loadingAlways provide loading states
Use useSearchParams without SuspenseEntire page silently falls back to CSRWrap in <Suspense> boundary
Use router.push() to close modalsBreaks history, modal can flash/persistUse router.back()
Use @vercel/og for OG imagesBuilt into Next.js alreadyImport from next/og
Omit default.tsx in parallel route slotsHard navigation (refresh) returns 404Add default.tsx returning null
Use Edge runtime unless requiredLimited APIs, most npm packages breakDefault Node.js runtime covers 95% of cases
Skip sizes prop on fill imagesDownloads largest image variant alwaysAdd sizes="100vw" or appropriate breakpoints
Import fonts in multiple componentsCreates duplicate instancesImport once in layout, use CSS variable
Use <link> for Google FontsNo optimization, blocks renderingUse next/font

Reference Files

FileTopic
rsc-boundaries.mdServer/Client boundary rules, serialization
data-patterns.mdFetching decision tree, waterfall avoidance
error-handling.mdError boundaries, redirect gotcha, auth errors
async-patterns.mdNext.js 15+ async params/cookies/headers
metadata.mdSEO, OG images, sitemaps, file conventions
parallel-routes.mdModal pattern, intercepting routes, gotchas
hydration-errors.mdCauses, debugging, fixes
self-hosting.mdDocker, PM2, cache handlers, deployment
file-conventions.mdProject structure, special files, middleware
bundling.mdThird-party packages, SSR issues, Turbopack
image-optimization.mdnext/image best practices
font-optimization.mdnext/font best practices
scripts.mdnext/script, third-party loading
route-handlers.mdAPI endpoints, request/response helpers

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

74.18%
按下载量换算7,261

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

未展示

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills