Client-Side Data Fetching in Next.js with SWR

SWR caches, deduplicates, and revalidates client-side requests. Learn to set up useSWR in a Client Component.

7 min read

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.

bashbash
npm i swr

The 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.tsxApp.tsx
// 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

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.
RunePowered by Rune AI

Frequently Asked Questions

Is SWR client-side or server-side?

Client-side. The useSWR hook runs in Client Components and cannot be imported into a Server Component.

What is the fetcher function?

A small function that SWR calls to load data, usually a wrapper around fetch that parses JSON.

Does SWR refetch automatically?

Yes, on window focus and network reconnect, and it deduplicates requests that share the same key.

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.