Use Server Components for server-side fetching, Route Handlers for APIs, client-side fetching for user-specific dynamic data, and Server Actions for mutations.
Next.js 13+ with the App Router provides several data fetching patterns, each suited to different scenarios.
Server Components can fetch data directly with async/await. Just write your database queries or API calls in the component: async function Posts() { const posts = await db.posts.findMany(); return ... }. Data fetches on the server, never exposes credentials to clients, and can be cached/revalidated.
Route Handlers (files named route.ts in app directory) create API endpoints. Use these when you need a traditional API: for webhooks, third-party integrations, or when clients need to fetch data dynamically.
Client-side fetching with useEffect, SWR, or TanStack Query is for data that depends on user interaction or needs real-time updates after initial load. The page renders first, then data loads. Good for dashboards with live data or user-specific content that can't be server-rendered.
Server Actions are functions marked with 'use server' that run on the server but can be called from client components. They're ideal for mutations (creating, updating, deleting data) and form submissions. They integrate with Next.js revalidation to keep your UI in sync.
General rule: fetch on the server when you can (faster, more secure), use client fetching when data depends on user state or needs live updates, and use Server Actions for mutations.
Use Server Components for server-side fetching, Route Handlers for APIs, client-side fetching for user-specific dynamic data, and Server Actions for mutations.
Join our network of elite AI-native engineers.