Client-side data fetching in Next.js with SWR means a hook owns the request instead of an effect. SWR is a React data fetching library that caches, deduplicates, and revalidates client-side requests.
You call a hook with a key and a fetcher, and it returns data, error, and loading state. The name stands for stale-while-revalidate, which describes how it serves cached data first and refreshes it in the background.
npm i swrThe package has no peer dependencies beyond React, so installing it is the whole setup. SWR also needs no global provider for the basic case, which keeps the setup to a single install command.
// app/profile/page.tsx
"use client";
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then((res) => res.json());
export default function ProfilePage() {
const { data, error, isLoading } = useSWR("/api/user", fetcher);
if (isLoading) return <p>Loading</p>;
if (error) return <p>Failed to load</p>;
return <h1>Hello, {data.name}</h1>;
}The hook runs on the client, which is why the file starts with the use client directive. The fetcher is a thin wrapper around fetch that parses JSON, and SWR calls it whenever the key has no fresh cached value. Any key works as long as it identifies the resource, from a plain URL string to an array combining a path and parameters.
What SWR handles for you
SWR caches responses by key, so two components asking for the same key share one request. It also revalidates on window focus and network reconnect, keeping data fresh without manual refreshes, and it can refetch on a fixed interval when you need live data. It also retries failed requests with a backoff, so a temporary network blip does not leave the page stuck on an error state.
States to handle
Every useSWR call reports three things: data, error, and isLoading. Render a loading state while the request is in flight, an error state when it fails, and the data when it succeeds. Skipping the error branch shows a blank component when a request fails.
SWR also exposes isValidating, which is true during a background refresh while stale data is still on screen. Use isLoading for the first paint and isValidating for a subtle refresh indicator.
Reusing a hook
Wrap useSWR in your own hook to share one request across components. Every component that calls the hook with the same key reads the same cached value, so the request is only made once and the data stays in sync everywhere it appears.
When to reach for SWR
Use SWR when the data belongs in a Client Component and changes often, such as a dashboard that needs live updates. For a mostly static page, server-side fetching is still the better default, and SWR earns its place when data changes during a session. For fetching on the server instead, see fetching without useEffect, and for seeding the cache with server data see hydrating client caches.
Rune AI
Key Insights
- SWR is a client-side data fetching hook.
- useSWR(key, fetcher) returns data, error, and isLoading.
- Requests sharing a key are deduplicated and cached.
- SWR revalidates on focus and network reconnect.
- The hook cannot run in Server Components.
Frequently Asked Questions
Is SWR client-side or server-side?
What is the fetcher function?
Does SWR refetch automatically?
Conclusion
SWR turns client-side fetching into a hook that caches, deduplicates, and revalidates for you. Set up a fetcher, call useSWR with a key, and render the loading, error, and data states it returns.
More in this topic
`generateMetadata` Explained with Real Examples
What generateMetadata does, when it runs, and how to use it for real routes: awaited params, deduplicated data fetching, extending parent metadata, and returning a 404 from metadata.
Canonical URLs in Next.js: `metadataBase`, `alternates.canonical`, and Dynamic Pages
How canonical URLs work in the Next.js App Router: setting metadataBase once, writing alternates.canonical per route, handling dynamic segments, and what happens when the base URL is missing.
Open Graph and Twitter Card Metadata in Next.js
How to write Open Graph and Twitter card metadata in the Next.js App Router: the openGraph and twitter fields, automatic card defaults, article tags, and image merge rules.