Client data fetching (SWR)

Pattern for client-side data fetching and revalidation using SWR.

Since App Router 13+ (SWR is a separate library) Spec ↗

Syntax

const { data, error, isLoading } = useSWR(key, fetcher)

Parameters

NameTypeRequiredDescription
key string | null Yes Unique cache key (often the URL); `null` to pause fetching.
fetcher (key) => Promise<T> Yes Function that resolves the data for the key.

Returns

{ data, error, isLoading, mutate } — Reactive client cache state.

Examples

'use client'
import useSWR from 'swr'

const fetcher = (url: string) => fetch(url).then((r) => r.json())

export function Profile() {
  const { data, error, isLoading } = useSWR('/api/me', fetcher)
  if (isLoading) return <p>Loading...</p>
  if (error) return <p>Failed</p>
  return <p>Hi {data.name}</p>
}
'use client'
import useSWR from 'swr'

// Live polling for client-only data
export function Stats() {
  const { data } = useSWR('/api/stats', (u) =>
    fetch(u).then((r) => r.json()), { refreshInterval: 5000 })
  return <span>{data?.online ?? 0} online</span>
}

Notes

For the App Router, prefer fetching in Server Components and passing data down. Use a client library like SWR (or TanStack Query) for highly interactive, frequently-updating, or client-only data (polling, infinite scroll, optimistic UI). Requires `'use client'`. Next has no built-in client `useFetch` hook.

See also