Loading...
Loading...
Next.js App Router development with TypeScript. Server Components, Server Actions, caching, MUI. Use when creating pages, components, fetching data, or building features.
npx skill4agent add carvalab/k-skills frontend-developmentRelated Skills:
- USE FIRST for Kavak-specific patterns, GitLab CI, Docker templateskavak-documentation - USE THIS for performance (bundle size, waterfalls, caching, re-renders, memoization)vercel-react-best-practices- Check
for project-specific conventions.claude/CLAUDE.md- Check
for project-specific conventions.cursor/rules/*MCP:
- Use
tool to query Kavak internal documentation before implementingkavak-platform/plati_query- Use
MCP server if available for debugging, route inspection, and build analysisnext-devtools
| Task | Pattern |
|---|---|
| New page | Server Component by default |
| Data fetching | Server Component async fetch |
| Mutations | Server Actions + Zod + revalidatePath |
| Styling | MUI |
| State | Server = fetch, Client = useState only when needed |
useStateuseEffect'use cache''use client'Performance: For bundle optimization, waterfalls, memoization, seevercel-react-best-practices
Need useState/useEffect/onClick? → 'use client'
Need browser APIs (localStorage)? → 'use client'
Just rendering data? → Server Component (default)// app/users/page.tsx - Server Component (default)
export default async function UsersPage() {
const users = await db.user.findMany(); // Runs on server
return <UserList users={users} />;
}// app/actions.ts
'use server';
import { z } from 'zod';
import { revalidatePath } from 'next/cache';
const schema = z.object({ title: z.string().min(1) });
export async function createPost(formData: FormData) {
const parsed = schema.safeParse({ title: formData.get('title') });
if (!parsed.success) return { error: parsed.error.flatten() };
await db.post.create({ data: parsed.data });
revalidatePath('/posts');
return { success: true };
}// ❌ Large 'use client' at top of tree
'use client'; // Marks entire subtree as client
// ❌ Expose secrets to client
const apiKey = process.env.SECRET_KEY; // In client component
// ❌ Old MUI Grid syntax
<Grid xs={12} md={6}>// ✅ Small leaf-level client components
// ✅ Validate Server Action inputs with Zod
// ✅ MUI Grid size prop
<Grid size={{ xs: 12, md: 6 }}>app/
├── layout.tsx # Root layout (Server)
├── page.tsx # Home page
├── loading.tsx # Loading UI (Suspense fallback)
├── error.tsx # Error boundary ('use client')
├── not-found.tsx # 404 page
├── users/
│ ├── page.tsx # /users
│ ├── [id]/
│ │ └── page.tsx # /users/:id
│ └── actions.ts # Server Actions
└── api/
└── webhook/
└── route.ts # Route Handler (public API)app/{route}/page.tsxloading.tsxactions.tsvercel-react-best-practicessxSxProps<Theme>.styles.tssize={{ xs: 12, md: 6 }}| Reference | When to Use |
|---|---|
| App Router, RSC, Server Actions, caching |
| React.FC, hooks order, dialogs, forms |
| MUI sx prop, Grid, theming |
| Types, generics, Zod validation |
| features/ vs components/, organization |
vercel-react-best-practices| Layer | Technology |
|---|---|
| Framework | Next.js (App Router, latest) |
| Type Safety | TypeScript (strict) + Zod |
| Data Fetching | Server Components (async) |
| Mutations | Server Actions + revalidatePath |
| Client State | useState (minimal) |
| Styling | MUI (latest) |
| Forms | Server Actions + useActionState |
references/data-fetching.md