You fetch data on the client with standard React patterns, either a useEffect call or a data fetching library. The page renders first, then the browser requests the data and updates the UI.
import { useState, useEffect } from 'react';
function Profile() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/user')
.then(res => res.json())
.then(data => {
setUser(data);
setLoading(false);
});
}, []);
if (loading) return <div>Loading...</div>;
return <div>Welcome, {user.name}!</div>;
}
This works, but you write loading and error handling yourself, and nothing caches or deduplicates the requests. A library such as SWR or React Query adds caching, revalidation and request deduplication, so it is the usual choice.
Client-side fetching suits data that is user-specific or changes often, and that search engines do not need to index. It is also the only option when the data depends on browser APIs. In the App Router this code must live in a Client Component marked with 'use client'. Prefer fetching in a Server Component when the data can be rendered on the server.
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.
Why there's no diagram: “”
The interactive diagram is below the answer - jump to diagram ↓ · Below it, the related concept . Jump to it ↓
The diagram below the answer is the concept . Jump to it ↓