mcpField
N
nextjs-15

nextjs-15

github.com/prowler-cloud开发15.2k94 次安装2 天前更新
代码仓库

关于 nextjs-15

用于 Next.js 15 应用开发的参考技能,面向构建 App Router 项目的开发者。内容涵盖文件约定,以及服务器组件、操作、数据获取、路由处理器、中间件和元数据示例。

主要功能

  1. 01App Router 文件约定
  2. 02服务器组件
  3. 03服务器操作
  4. 04数据获取模式
  5. 05路由处理器与中间件
  6. 06静态和动态元数据

适用场景

  1. 01组织 App Router 项目结构
  2. 02实现服务器端表单操作
  3. 03添加 API 路由处理器
  4. 04配置中间件和页面元数据

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/prowler-cloud/prowler --skill nextjs-15

安装后在 Claude Code 中输入/nextjs-15确认已加载。

详细介绍

App Router 文件约定

app/
├── layout.tsx          # Root layout (required)
├── page.tsx            # Home page (/)
├── loading.tsx         # Loading UI (Suspense)
├── error.tsx           # Error boundary
├── not-found.tsx       # 404 page
├── (auth)/             # Route group (no URL impact)
│   ├── login/page.tsx  # /login
│   └── signup/page.tsx # /signup
├── api/
│   └── route.ts        # API handler
└── _components/        # Private folder (not routed)

服务器组件(默认)

// No directive needed - async by default
export default async function Page() {
  const data = await db.query();
  return <Component data={data} />;
}

服务器操作

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

import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";

export async function createUser(formData: FormData) {
  const name = formData.get("name") as string;

  await db.users.create({ data: { name } });

  revalidatePath("/users");
  redirect("/users");
}

// Usage
<form action={createUser}>
  <input name="name" required />
  <button type="submit">Create</button>
</form>

数据获取

// Parallel
async function Page() {
  const [users, posts] = await Promise.all([
    getUsers(),
    getPosts(),
  ]);
  return <Dashboard users={users} posts={posts} />;
}

// Streaming with Suspense
<Suspense fallback={<Loading />}>
  <SlowComponent />
</Suspense>

路由处理程序(API)

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

export async function GET(request: NextRequest) {
  const users = await db.users.findMany();
  return NextResponse.json(users);
}

export async function POST(request: NextRequest) {
  const body = await request.json();
  const user = await db.users.create({ data: body });
  return NextResponse.json(user, { status: 201 });
}

中间件

// middleware.ts (root level)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const token = request.cookies.get("token");

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

  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*"],
};

元数据

// Static
export const metadata = {
  title: "My App",
  description: "Description",
};

// Dynamic
export async function generateMetadata({ params }) {
  const product = await getProduct(params.id);
  return { title: product.name };
}

server-only Package

import "server-only";

// This will error if imported in client component
export async function getSecretData() {
  return db.secrets.findMany();
}

评论

支持 Markdown