SimpleNext.js

Simple data fetching with SWR in Next.js

Cover Image for Simple data fetching with SWR in Next.js
Marouane Reda
Marouane Reda

SWR is a React hook for data fetching that is lightweight, fast and easy to use. More importantly it is perfect fot Next.js as it supports both Static Generation (SSG) and Server-side Rendering (SSR).

What is SWR

SWR is a React Hooks library for data fetching based on the SWR strategy. SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.

Example with a REST API

In our REST API article, we used SWR to fetch data from our API :

import useSwr from 'swr'
import Link from 'next/link'

const fetcher = (url) => fetch(url).then((res) => res.json())

export default function Index() {
  const { data, error } = useSwr('/api/users', fetcher)

  if (error) return <div>Failed to load users</div>
  if (!data) return <div>Loading...</div>

  return (
    <ul>
      {data.map((user) => (
        <li key={user.id}>
          <Link href="/user/[id]" as={`/user/${user.id}`}>
            <a>{`User ${user.id}`}</a>
          </Link>
        </li>
      ))}
    </ul>
  )
}

In this example, the useSWR hook accepts a key string and a fetcher function. key is a unique identifier of the data (here the API URL) and will be passed to fetcher. fetcher can be any asynchronous function which returns the data, you can use the native fetch as we did in the example or tools like Axios.

The hook returns 2 values: data and error, based on the status of the request.

Axios

As easy as :

import axios from 'axios'

const fetcher = url => axios.get(url).then(res => res.data)

function App () {
  const { data, error } = useSWR('/api/data', fetcher)
  // ...
}

GraphQL

You can use GraphQL with libs like graphql-request:

import { request } from 'graphql-request'

const fetcher = query => request('/api/graphql', query)

function App () {
  const { data, error } = useSWR(
    `{
      Book(title: "Rich dad, poor dad") {
        releaseDate
        author {
          name
        }
      }
    }`,
    fetcher
  )
  // ...
}

Use SWR to get initial data for Next.js pages

You can pass the pre-fetched data as the initial value to the initialData option. For example together with getStaticProps:

export async function getStaticProps() {
  // `getStaticProps` is invoked on the server-side,
  // so this `fetcher` function will be executed on the server-side.
  const posts = await fetcher('https://jsonplaceholder.typicode.com/posts')
  return { props: { posts } }
}

function Posts (props) {
  // Here the `fetcher` function will be executed on the client-side.
  const { data } = useSWR('/api/posts', fetcher, { initialData: props.posts })

  // ...
}