)
}
```
---
### ⚡ Performance
**Optimization Patterns:**
- Use Server Components (smaller bundle)
- Use `next/image` for images
- Use `next/font` for fonts
- Lazy load Client Components when possible
- Use `useMemo` and `useCallback` in Client Components
- Stream data with Suspense boundaries
**Image Optimization:**
```typescript
import Image from 'next/image'
export function Avatar({ src, alt }: { src: string; alt: string }) {
return (
)
}
```
**Streaming with Suspense:**
```typescript
import { Suspense } from 'react'
import { PostList } from '@/components/PostList'
import { Loading } from '@/components/Loading'
export default function Page() {
return (
}>
)
}
```
---
### 📘 TypeScript
**Standards:**
- Strict mode enabled
- No `any` type
- Explicit return types on functions
- Type imports: `import type { Post } from '@/types/post'`
- Component prop interfaces with JSDoc
**Example:**
```typescript
import type { ComponentProps } from 'react'
import { Button } from '@/components/ui/button'
/**
* Custom button component with loading state
*/
interface CustomButtonProps extends ComponentProps {
isLoading?: boolean
}
export function CustomButton({
isLoading,
children,
...props
}: CustomButtonProps) {
return (
)
}
```
---
### 🔧 Common Patterns
**Form Handling:**
- Use Server Actions for form submissions
- Use `react-hook-form` with `zod` for validation (Client Components)
- Use Shadcn/ui Form components
**Example Form with Server Action:**
```typescript
// app/actions/posts.ts
'use server'
import { z } from 'zod'
const createPostSchema = z.object({
title: z.string().min(1),
content: z.string().min(1),
})
export async function createPost(formData: FormData) {
const rawData = {
title: formData.get('title'),
content: formData.get('content'),
}
const validated = createPostSchema.parse(rawData)
// ... create post logic
redirect('/posts')
}
```
**Metadata:**
```typescript
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Posts',
description: 'List of all posts',
openGraph: {
title: 'Posts',
description: 'List of all posts',
},
}
```
---
## Core Principles
1. **Server Components First**: Default to Server Components, use Client Components only when needed
2. **App Router Structure**: Use file-based routing with `app/` directory
3. **Shadcn/ui Components**: Use pre-built accessible components
4. **Tailwind CSS**: Utility-first styling with `cn()` helper
5. **TypeScript Strict**: No `any`, explicit types
6. **Performance**: Use Server Components, optimize images, lazy load when needed
7. **File Organization**: Features in `app/features/`, shared in `components/`
8. **Import Aliases**: Use `@/` prefix for clean imports
---
## Quick Reference: File Structure
```
app/
layout.tsx # Root layout
page.tsx # Home page
globals.css # Global styles
(routes)/
posts/
page.tsx # Posts list page
[id]/
page.tsx # Post detail page
loading.tsx # Loading UI
error.tsx # Error UI
features/
posts/
components/
PostList.tsx # Feature components
actions/
posts.ts # Server Actions
components/
ui/ # Shadcn/ui components
button.tsx
card.tsx
lib/
utils.ts # Utilities (cn, etc.)
hooks/
use-mobile.ts # Custom hooks
```
---
## Modern Component Template (Quick Copy)
**Server Component:**
```typescript
// app/components/PostCard.tsx
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import type { Post } from '@/types/post'
interface PostCardProps {
post: Post
}
export function PostCard({ post }: PostCardProps) {
return (
{post.title}
{post.content}
)
}
```
**Client Component:**
```typescript
// app/components/PostForm.tsx
'use client'
import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { createPost } from '@/app/actions/posts'
import { cn } from '@/lib/utils'
export function PostForm({ className }: { className?: string }) {
const [isLoading, setIsLoading] = useState(false)
async function handleSubmit(formData: FormData) {
setIsLoading(true)
await createPost(formData)
setIsLoading(false)
}
return (
)
}
```
---
## Related Skills
- **backend-dev-guidelines**: Backend API patterns that frontend consumes
---
**Skill Status**: Optimized for Next.js 15 with App Router, Server Components, and Shadcn/ui