---
description: Next.js development standards and patterns
globs: "app/**/*.{ts,tsx}"
---

# Next.js Rules

## **Core Principles**
- **Default to Server Components** for better performance.
- **Minimize `'use client'` directives** to leverage SSR benefits.
- Follow **App Router patterns and conventions**.
- **Handle errors properly** using `error.tsx` and **error boundaries**.
- Use **Next.js 15 built-in components** (`Image`, `Link`, `Script`, `Head`, etc.).
- Optimize **Web Vitals** (`LCP`, `CLS`, `FID`).

### **Key Conventions**
- Use **`nuqs`** for URL search parameter state management.
- **Limit `'use client'`**:
  - Favor **Server Components** and **Next.js SSR**.
  - Use only for **Web API access in small components**.
  - Avoid for **data fetching or state management**.

---

## **Component Architecture**
```tsx
// Prefer Server Components by default
export function ServerComponent() {
  return (
    <section className="space-y-4">
      <h1>Server Rendered</h1>
      <ClientComponent />
    </section>
  )
}

// Use 'use client' only when necessary
'use client'
function ClientComponent() {
  const [state, setState] = useState(false)
  return <button onClick={() => setState(!state)}>Toggle</button>
}
```

---

## **Data Fetching**
- **Use Server Components** for data fetching.
- **Implement proper caching strategies**.
- **Handle loading and error states**.
- **Use revalidation patterns** to optimize freshness.

---

## **Server Actions**
```tsx
'use server'
import { type ActionResult, success, failure } from '@chaingraph/next'
import { createSafeActionClient } from 'next-safe-action'

export const saveAction = createSafeActionClient()
  .schema(actionSchema)
  .action(async ({ parsedInput }): Promise<ActionResult<T>> => {
    try {
      // Happy path
      return success(result)
    } catch (error) {
      return failure({
        code: 'UNEXPECTED_ERROR',
        error,
        label: 'saveAction'
      })
    }
  })
```

---

## **Performance Patterns**
```tsx
// Use Image component with proper sizing
import { Image } from 'next/image'

export function OptimizedImage() {
  return (
    <Image
      src="/hero.webp"
      alt="Hero"
      width={1200}
      height={630}
      priority={true}
      className="w-full"
    />
  )
}

// Use Suspense for loading states
export function LazyComponent() {
  return (
    <Suspense fallback={<LoadingSkeleton />}>
      <ExpensiveComponent />
    </Suspense>
  )
}
```

---

## **Next.js Optimizations**
- **Use App Router** with `nuqs` for efficient navigation and state management.
- **Implement streaming** with `Suspense` for progressive loading.
- **Follow proper caching strategies**:
  - Use `fetch` cache options appropriately.
  - Implement **revalidation when needed**.
- **Minimize `'use client'`**, `'useEffect'`, and `'setState'` in favor of **React Server Components (RSC)**.
- **Wrap client components** in `Suspense` with a fallback.
- **Use dynamic loading** for non-critical components.
- **Optimize images**:
  - Use **WebP format**.
  - Include **size data**.
  - Implement **lazy loading**.

---

## **UI & Styling**
- **Use Shadcn UI, Radix, and Tailwind** for components and styling.
- **Implement responsive design** with **Tailwind CSS** using a **mobile-first approach**.
