| name | nextjs-app-router-data-fetching |
| version | 1.0 |
| description | Data fetching patterns for Next.js 14+ App Router including async Server Components and Server Actions. PROACTIVELY activate for: (1) fetching data in Server Components, (2) implementing Server Actions for mutations, (3) configuring caching and revalidation. Triggers: "fetch data", "server action", "revalidate"
|
| group | foundation |
| core-integration | {"techniques":{"primary":["structured_decomposition"],"secondary":[]},"contracts":{"input":"none","output":"none"},"patterns":"none","rubrics":"none"} |
Next.js App Router Data Fetching
Pattern 1: Async Server Components (Recommended)
export default async function PostsPage() {
const posts = await fetch('https://api.example.com/posts', {
next: { revalidate: 60 }
}).then(res => res.json());
return (
<div>
{posts.map(post => (
<article key={post.id}>{post.title}</article>
))}
</div>
);
}
Benefits:
- No loading spinners (rendered on server)
- No client-server waterfalls
- Can access database directly (no API layer needed)
- Automatic request deduplication
Pattern 2: Server Actions (For Mutations)
'use server'
import { revalidatePath } from 'next/cache';
export async function createPost(formData: FormData) {
const title = formData.get('title');
await db.post.create({ data: { title } });
revalidatePath('/posts');
return { success: true };
}
import { createPost } from '@/app/actions/posts';
export default function NewPostPage() {
return (
<form action={createPost}>
<input name="title" />
<button type="submit">Create</button>
</form>
);
}
Caching Strategies
fetch('...', { cache: 'no-store' })
fetch('...', { cache: 'force-cache' })
fetch('...', { next: { revalidate: 3600 } })
fetch('...', { next: { tags: ['posts'] } })
Anti-Pattern: useEffect for Data Fetching
'use client'
function Posts() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('/api/posts').then(r => r.json()).then(setPosts);
}, []);
return
}
async function Posts() {
const posts = await fetch('...').then(r => r.json());
return
}
Parallel Data Fetching
export default async function Page() {
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments(),
]);
return
}
For database integration and advanced caching, see resources/database-patterns.md.