Token导航 LogoToken导航

Agent Skill · 研究检索

nextjs-expert(Next.js expert 前端)

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

nextjs-expert 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 69,522。

总安装 218周安装 9GitHub Stars 17下载 71核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

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

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

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/nguyenthienthanh/aura-frog --skill nextjs-expert

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于辅助前端页面、组件和样式开发,适合生成或审查 React/Next.js 代码。适用于组件结构整理、布局问题和性能优化排查。需结合设计系统和路由方式,避免生成孤立片段。安装方式:通过 GitHub 仓库安装,使用前确认权限与维护状态。涉及页面改动时,应配合本地预览和构建检查确认效果。

来源仓库内路径:skills/nextjs-expert

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/nguyenthienthanh/aura-frog --skill nextjs-expe…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

nextjs-expert 怎么安装?

在终端执行 npx skills add https://github.com/nguyenthienthanh/aura-frog --skill nextjs-expert。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

nextjs-expert 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

nextjs-expert 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

nextjs-expert 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

nextjs-expert 用的人多吗?

公开数据是累计安装 218 次,近一周安装 9 次,下载 71 次,GitHub 17 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

nextjs-expert 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
nextjs-expert

Next.js expert 前端 · 本页

21817需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Next.js Expert Skill

Expert-level Next.js 14+ patterns, App Router, Server Components, data fetching, and optimization.


Auto-Detection

This skill activates when:

  • Working with Next.js projects
  • Detected next in package.json
  • Working with App Router structure (app/ directory)
  • Building API routes or Server Components

1. App Router Structure

Recommended Structure

app/
├── (auth)/                    # Route group (no URL impact)
│   ├── login/
│   │   └── page.tsx
│   └── register/
│       └── page.tsx
├── (dashboard)/
│   ├── layout.tsx            # Shared dashboard layout
│   ├── page.tsx              # /dashboard
│   └── settings/
│       └── page.tsx          # /dashboard/settings
├── api/
│   └── users/
│       └── route.ts          # API route
├── layout.tsx                # Root layout
├── page.tsx                  # Home page
├── loading.tsx               # Loading UI
├── error.tsx                 # Error UI
├── not-found.tsx             # 404 page
└── global-error.tsx          # Global error boundary

File Conventions

file_conventions[8]{file,purpose}:
  page.tsx,Route UI component
  layout.tsx,Shared layout (preserves state)
  template.tsx,Shared layout (re-renders)
  loading.tsx,Loading UI (Suspense)
  error.tsx,Error boundary
  not-found.tsx,404 page
  route.ts,API endpoint
  middleware.ts,Request middleware

2. Server vs Client Components

Server Components (Default)

// ✅ GOOD - Server Component (default, no directive needed)
// app/users/page.tsx
import { db } from '@/lib/db';

export default async function UsersPage() {
  // Direct database access - runs on server only
  const users = await db.user.findMany();

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Client Components

// ✅ GOOD - Client Component (explicit directive)
'use client';

import { useState } from 'react';

export function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(c => c + 1)}>
      Count: {count}
    </button>
  );
}

Component Boundaries

// ✅ GOOD - Keep client boundary as low as possible
// app/dashboard/page.tsx (Server Component)
import { getUser } from '@/lib/auth';
import { UserProfile } from './UserProfile';
import { InteractiveChart } from './InteractiveChart'; // Client

export default async function DashboardPage() {
  const user = await getUser();

  return (
    <div>
      {/* Server Component - no JS shipped */}
      <UserProfile user={user} />

      {/* Client Component - only this ships JS */}
      <InteractiveChart data={user.stats} />
    </div>
  );
}

3. Data Fetching

Server Component Fetching

// ✅ GOOD - Fetch in Server Component
async function getData() {
  const res = await fetch('https://api.example.com/data', {
    // Cache options
    cache: 'force-cache',      // Default - cached indefinitely
    // cache: 'no-store',      // No caching
    // next: { revalidate: 60 }, // Revalidate every 60s
    // next: { tags: ['posts'] }, // Tag-based revalidation
  });

  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }

  return res.json();
}

export default async function Page() {
  const data = await getData();
  return <div>{/* render data */}</div>;
}

Parallel Data Fetching

// ✅ GOOD - Parallel fetching
export default async function Page() {
  // Start both fetches simultaneously
  const userPromise = getUser();
  const postsPromise = getPosts();

  // Wait for both
  const [user, posts] = await Promise.all([userPromise, postsPromise]);

  return (
    <div>
      <UserProfile user={user} />
      <PostList posts={posts} />
    </div>
  );
}

Streaming with Suspense

// ✅ GOOD - Stream slow data
import { Suspense } from 'react';

export default function Page() {
  return (
    <div>
      {/* Renders immediately */}
      <Header />

      {/* Streams when ready */}
      <Suspense fallback={<PostsSkeleton />}>
        <Posts />
      </Suspense>

      <Suspense fallback={<CommentsSkeleton />}>
        <Comments />
      </Suspense>
    </div>
  );
}

// Async Server Component
async function Posts() {
  const posts = await getPosts(); // Slow fetch
  return <PostList posts={posts} />;
}

4. Server Actions

Form Actions

// ✅ GOOD - Server Action in separate file
// app/actions.ts
'use server';

import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { z } from 'zod';

const CreatePostSchema = z.object({
  title: z.string().min(1),
  content: z.string().min(10),
});

export async function createPost(formData: FormData) {
  const validatedFields = CreatePostSchema.safeParse({
    title: formData.get('title'),
    content: formData.get('content'),
  });

  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
    };
  }

  const { title, content } = validatedFields.data;

  await db.post.create({ data: { title, content } });

  revalidatePath('/posts');
  redirect('/posts');
}
// ✅ GOOD - Form with Server Action
// app/posts/new/page.tsx
import { createPost } from '@/app/actions';

export default function NewPostPage() {
  return (
    <form action={createPost}>
      <input name="title" placeholder="Title" required />
      <textarea name="content" placeholder="Content" required />
      <SubmitButton />
    </form>
  );
}

// Client component for pending state
'use client';
import { useFormStatus } from 'react-dom';

function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? 'Creating...' : 'Create Post'}
    </button>
  );
}

useActionState (React 19)

'use client';

import { useActionState } from 'react';
import { createPost } from '@/app/actions';

export function CreatePostForm() {
  const [state, formAction, isPending] = useActionState(createPost, null);

  return (
    <form action={formAction}>
      <input name="title" />
      {state?.errors?.title && <p>{state.errors.title}</p>}

      <textarea name="content" />
      {state?.errors?.content && <p>{state.errors.content}</p>}

      <button disabled={isPending}>
        {isPending ? 'Creating...' : 'Create'}
      </button>
    </form>
  );
}

5. API Routes

Route Handlers

// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';

// GET /api/users
export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams;
  const page = searchParams.get('page') ?? '1';

  const users = await db.user.findMany({
    skip: (parseInt(page) - 1) * 10,
    take: 10,
  });

  return NextResponse.json(users);
}

// POST /api/users
export async function POST(request: NextRequest) {
  const body = await request.json();

  const user = await db.user.create({ data: body });

  return NextResponse.json(user, { status: 201 });
}

Dynamic Routes

// app/api/users/[id]/route.ts
import { NextRequest, NextResponse } from 'next/server';

type Params = { params: { id: string } };

export async function GET(request: NextRequest, { params }: Params) {
  const user = await db.user.findUnique({
    where: { id: params.id },
  });

  if (user == null) {
    return NextResponse.json({ error: 'Not found' }, { status: 404 });
  }

  return NextResponse.json(user);
}

export async function DELETE(request: NextRequest, { params }: Params) {
  await db.user.delete({ where: { id: params.id } });
  return new NextResponse(null, { status: 204 });
}

6. Middleware

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Check auth
  const token = request.cookies.get('token');

  if (token == null && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // Add headers
  const response = NextResponse.next();
  response.headers.set('x-request-id', crypto.randomUUID());

  return response;
}

export const config = {
  matcher: [
    // Match all paths except static files
    '/((?!_next/static|_next/image|favicon.ico).*)',
  ],
};

7. Metadata & SEO

Static Metadata

// app/page.tsx
import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'Home | My App',
  description: 'Welcome to my app',
  openGraph: {
    title: 'Home | My App',
    description: 'Welcome to my app',
    images: ['/og-image.png'],
  },
};

export default function HomePage() {
  return <main>...</main>;
}

Dynamic Metadata

// app/posts/[slug]/page.tsx
import type { Metadata } from 'next';

type Props = { params: { slug: string } };

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const post = await getPost(params.slug);

  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [post.coverImage],
    },
  };
}

export default async function PostPage({ params }: Props) {
  const post = await getPost(params.slug);
  return <article>{/* ... */}</article>;
}

8. Caching & Revalidation

Cache Strategies

cache_strategies[4]{strategy,use_case,code}:
  Static,Rarely changes,cache: 'force-cache'
  Time-based,Updates periodically,next: { revalidate: 60 }
  On-demand,User-triggered,revalidatePath() / revalidateTag()
  No cache,Always fresh,cache: 'no-store'

On-Demand Revalidation

// app/actions.ts
'use server';

import { revalidatePath, revalidateTag } from 'next/cache';

export async function updatePost(id: string, data: PostData) {
  await db.post.update({ where: { id }, data });

  // Revalidate specific path
  revalidatePath(`/posts/${id}`);

  // Or revalidate by tag
  revalidateTag('posts');
}

// In fetch
const posts = await fetch('https://api.example.com/posts', {
  next: { tags: ['posts'] },
});

9. Image Optimization

import Image from 'next/image';

// ✅ GOOD - Optimized image
<Image
  src="/hero.jpg"
  alt="Hero image"
  width={1200}
  height={600}
  priority // Load immediately (LCP)
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>

// ✅ GOOD - Fill container
<div className="relative h-64 w-full">
  <Image
    src={post.coverImage}
    alt={post.title}
    fill
    sizes="(max-width: 768px) 100vw, 50vw"
    className="object-cover"
  />
</div>

// ✅ GOOD - Remote images (configure in next.config.js)
// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      { protocol: 'https', hostname: 'cdn.example.com' },
    ],
  },
};

10. Error Handling

// app/error.tsx (Client Component required)
'use client';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}

// app/global-error.tsx (Root layout errors)
'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>
  );
}

Quick Reference

checklist[12]{pattern,best_practice}:
  Components,Server by default Client when needed
  Client directive,'use client' at top of file
  Data fetching,Fetch in Server Components
  Parallel fetch,Promise.all for multiple fetches
  Streaming,Suspense for slow data
  Forms,Server Actions + useFormStatus
  API routes,Route handlers in app/api
  Caching,Tag-based revalidation
  Images,next/image with sizes prop
  Metadata,generateMetadata for dynamic
  Errors,error.tsx at route level
  Loading,loading.tsx for Suspense

平台分布

OpenCode

29.33%
按下载量换算21

Claude Code

21.14%
按下载量换算15

windsurf

18.88%
按下载量换算13

cline

11.29%
按下载量换算8

weavefox

7.72%
按下载量换算5

Codex

3.23%
按下载量换算2

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills