react-nextjs
9
总安装量
4
周安装量
#32855
全站排名
安装命令
npx skills add https://github.com/alicoder001/agent-skills --skill react-nextjs
Agent 安装分布
openclaw
4
opencode
4
cursor
4
codex
4
claude-code
4
antigravity
4
Skill 文档
Next.js App Router Best Practices
Next.js 14+ with Vercel optimization patterns.
Instructions
1. App Router Structure
app/
âââ layout.tsx # Root layout
âââ page.tsx # Home page
âââ loading.tsx # Loading UI
âââ error.tsx # Error UI
âââ not-found.tsx # 404 page
âââ (auth)/ # Route group
â âââ login/
â âââ register/
âââ api/
âââ users/
âââ route.ts # API route
2. Server vs Client Components
// â
Server Component (default) - no directive
async function UserList() {
const users = await getUsers(); // Direct DB access
return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
// â
Client Component - needs interactivity
'use client';
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
3. Prevent Request Waterfall
// â Bad - sequential (waterfall)
async function Page() {
const user = await getUser();
const posts = await getPosts(user.id);
const comments = await getComments(posts[0].id);
return ...;
}
// â
Good - parallel with Promise.all
async function Page() {
const [user, posts] = await Promise.all([
getUser(),
getPosts()
]);
return ...;
}
// â
Good - defer non-critical
async function Page() {
const user = await getUser();
const postsPromise = getPosts(user.id); // Don't await yet
return (
<div>
<UserProfile user={user} />
<Suspense fallback={<PostsSkeleton />}>
<Posts promise={postsPromise} />
</Suspense>
</div>
);
}
4. No Barrel Files (Bundle Optimization)
// â Bad - barrel file imports entire module
import { Button, Card } from '@/components';
// â
Good - direct imports
import { Button } from '@/components/Button';
import { Card } from '@/components/Card';
5. Dynamic Imports
// â
Lazy load heavy components
import dynamic from 'next/dynamic';
const HeavyChart = dynamic(() => import('@/components/Chart'), {
loading: () => <ChartSkeleton />,
ssr: false
});
6. Server Actions
// app/actions.ts
'use server';
import { revalidatePath } from 'next/cache';
export async function createPost(formData: FormData) {
const title = formData.get('title');
await db.post.create({ data: { title } });
revalidatePath('/posts');
}
// Usage in component
<form action={createPost}>
<input name="title" />
<button type="submit">Create</button>
</form>
7. Caching Strategies
// â
React.cache for request deduplication
import { cache } from 'react';
export const getUser = cache(async (id: string) => {
return await db.user.findUnique({ where: { id } });
});
// â
Next.js fetch cache
const data = await fetch(url, {
next: { revalidate: 3600 } // Revalidate hourly
});
// â
Static generation
export const dynamic = 'force-static';
8. Metadata
// Static metadata
export const metadata: Metadata = {
title: 'My App',
description: 'Description...'
};
// Dynamic metadata
export async function generateMetadata({ params }): Promise<Metadata> {
const product = await getProduct(params.id);
return { title: product.name };
}