nextjs-data-fetching
Apply when fetching data in Next.js App Router: server components, caching strategies, revalidation, and streaming.
When & Why to Use This Skill
This Claude skill provides comprehensive patterns and best practices for data fetching within the Next.js App Router. It enables developers to implement efficient Server Components, manage complex caching strategies, and utilize streaming with Suspense to build high-performance, SEO-friendly web applications. By following these industry-standard patterns, developers can optimize Core Web Vitals and streamline their full-stack React development workflow.
Use Cases
- Implementing Server Component data fetching to improve initial page load and reduce the JavaScript bundle size sent to the client.
- Configuring advanced caching strategies, including time-based revalidation and on-demand tag-based revalidation (ISR), to balance data freshness and server performance.
- Optimizing application performance by replacing sequential awaits with parallel data fetching patterns to eliminate request waterfalls.
- Enhancing user experience for data-heavy pages by implementing streaming with React Suspense boundaries and loading skeletons.
- Handling secure data mutations and automatic cache invalidation using Next.js Server Actions and the revalidatePath API.
| name | nextjs-data-fetching |
|---|---|
| description | Apply when fetching data in Next.js App Router: server components, caching strategies, revalidation, and streaming. |
| version | 1.0.0 |
| tokens | ~700 |
| confidence | high |
| - https | //nextjs.org/docs/app/building-your-application/caching |
| last_validated | 2025-01-10 |
| next_review | 2025-01-24 |
| tags | [nextjs, data-fetching, caching, ssr] |
When to Use
Apply when fetching data in Next.js App Router: server components, caching strategies, revalidation, and streaming.
Patterns
Pattern 1: Server Component Fetch
// Source: https://nextjs.org/docs/app/building-your-application/data-fetching
// app/posts/page.tsx - Server Component (default)
async function PostsPage() {
const posts = await fetch('https://api.example.com/posts', {
next: { revalidate: 3600 }, // Revalidate every hour
}).then((r) => r.json());
return <PostList posts={posts} />;
}
Pattern 2: Caching Strategies
// Source: https://nextjs.org/docs/app/building-your-application/caching
// Force cache (default) - cached indefinitely
fetch(url); // or { cache: 'force-cache' }
// Revalidate time-based
fetch(url, { next: { revalidate: 60 } }); // 60 seconds
// Revalidate on-demand (via tag)
fetch(url, { next: { tags: ['posts'] } });
// Then: revalidateTag('posts') in server action
// No cache - always fresh
fetch(url, { cache: 'no-store' });
Pattern 3: Parallel Data Fetching
// Source: https://nextjs.org/docs/app/building-your-application/data-fetching/patterns
async function Dashboard() {
// Parallel fetches - don't await sequentially
const [user, posts, analytics] = await Promise.all([
getUser(),
getPosts(),
getAnalytics(),
]);
return (
<>
<UserCard user={user} />
<PostList posts={posts} />
<Analytics data={analytics} />
</>
);
}
Pattern 4: Streaming with Suspense
// Source: https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
import { Suspense } from 'react';
async function SlowComponent() {
const data = await fetchSlowData(); // 3+ seconds
return <Chart data={data} />;
}
export default function Page() {
return (
<>
<h1>Dashboard</h1>
<FastComponent /> {/* Renders immediately */}
<Suspense fallback={<ChartSkeleton />}>
<SlowComponent /> {/* Streams in when ready */}
</Suspense>
</>
);
}
Pattern 5: Server Actions for Mutations
// Source: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations
'use server';
import { revalidatePath } from 'next/cache';
export async function createPost(formData: FormData) {
const title = formData.get('title');
await db.posts.create({ data: { title } });
revalidatePath('/posts'); // Refresh the posts page cache
}
// In component:
<form action={createPost}>
<input name="title" />
<button type="submit">Create</button>
</form>
Anti-Patterns
- Sequential awaits - Use Promise.all for independent fetches
- Client fetch for initial data - Fetch in server component instead
- No revalidation strategy - Always define cache behavior
- Fetching in layout without need - Layouts cache across navigations
Verification Checklist
- Data fetched in server components (not client)
- Caching strategy defined (revalidate time or tags)
- Independent fetches run in parallel
- Slow data wrapped in Suspense
- Mutations use server actions with revalidation