[ad_1]

Quick summary ↬

When linked to ISR and Next.js API routes, SWR can be used to create a responsive user experience. In this article, Sam Poder explains what SWR is, where to use it (and where not) and how to build a website using Incremental Static Regeneration.

If you have ever used Incremental Static Regeneration (ISR) with Next.jsYou may have sent outdated data to the client. This happens when you revalidate the page on the server. For some sites it works, but for others (such as Hack Club Scrapbook, a website built by @lachlanjc which I help maintain), the user expects the data to be kept up to date.

The first solution you can think of is to display only the pages on the server side, to ensure that the client is always sent the latest data. However, retrieving large pieces of data before it is displayed may delay the initial loading of the page. The solution used in Scrapbook was to use the SWR library of React hooks update the cache in the cache from the server with data download from the client. This approach ensures that users still have a good experience, that the website is fast and that the data is kept up to date.

Meet SWR

SWR is a React Hooks library built by Vercel, the name comes from the term old-while-revalidate. As the name suggests, your client will receive old / old data, while the latest data is retrieved (revalued) by SWR on the client side. SWR not only validates the data once, but you can configure SWR to revalidate the data at an interval, when the page is refocused, when a client reconnects to the Internet or reconnects programmatically.

When linked to ISR and Next.js API routes, SWR can be used to create a responsive user experience. The client is first served with the statically generated page in the cache (generated with getStaticProps()), in the background the server also starts the process of revalidating the page (read more here). This process feels fast for the customer and they can now see the set of data, but it may be a bit outdated. Once the page is loaded, a fetch request for a Next.js API route is made from you, which returns the same data as it was generated with getStaticProps(). If this request is completed (if accepted), SWR will update the page with this new data.

Let’s now look back at Scrapbook and how it helped solve the problem of having old data on the page. The obvious thing is that the customer is now getting an updated version. The more interesting, however, is the impact on the speed on our part. If we measure speed through the lighthouse, we get a speed index of 1.5 seconds for the ISR + SWR variant of the website and 5.8 seconds for the server-side version (plus a warning regarding the initial response time of the server). This is a pretty strong contrast between the two (and it was also noticeable when loading the pages). But there is also a trade-off, but on the server-side version page, the user did not change the layout of the site after a few seconds, but I believe Scrapbook handles this update well. design the experience of your user.

More to jump! Read more below ↓

Where to use SWR (and where not)

SWR can be set up in different places; here are some site categories where SWR can fit very well:

  • Websites with live data that need to be updated quickly.
    Examples of such sites would be sites for sports scores and flight tracking. If you are building these sites, you will want to use the interval revaluation option with a low interval setting (one to five seconds).
  • Websites with a feed style of updates or postings that are updated in real time.
    The classic example of this is the news sites with live blogs of events such as elections. Another example would also be the above scrapbook. In this case, you probably also want to use the interval revalidation option, but with a higher interval setting (thirty to sixty seconds) to save on data usage and avoid unnecessary API calls.
  • Websites with more passive data updates that keep people very open in the background.
    Examples of these sites are back pages or in the COVID-19 case number pages in 2020. These pages do not update as often and therefore do not require the constant re-validation of the previous two examples. However, it will still improve the user experience for updating the data. In these cases, I recommend that the date on which the page refocuses and when a customer reconnects to the Internet be reconfirmed, which means that if a person anxiously returns to the tap, in the hope that there is only a small increase in COVID cases was getting the data fast.
  • Websites with small pieces of data that users can communicate with.
    Think of the Youtube Subscribe button, when you click on subscribe, you want to see the score change and feel like you have made a difference. In these cases, you can programmatically revalidate the data using SWR to retrieve the new score and update the displayed amount.

One thing to note is that it can all be applied with or without ISR.

Of course, there are places where you do not want to use SWR or use SWR without ISR. SWR is not widely used if your data is not infrequently changed or altered, but rather can block your network requests and deplete the mobile user’s data. SWR can work with pages that require authentication, but in these cases you want to use server rendering, not incremental static revival.

Use SWR with Next.js and incremental static revival

Now that we have examined the theory of this strategy, let us examine how we can put it into practice. For this we are going to build a website that shows how many taxis are available in Singapore (where I live!) this API provided by the government.

Project structure

Our project works with three files:

  • lib/helpers.js
  • pages/index.js (our front page file)
  • pages/api/index.js (our API file)

Our helpers file will perform a function (getTaxiData) which will retrieve the data from the external API and then return it in a suitable format for our use. Our API file will import the function and set its default export to a handler function that the getTaxiData function and then send it back, this means that a GET request must be sent to /api will return our data.

SWR requires this capability to retrieve data to the client. Finally, we will import into our front-end file getTaxiData and use it in getStaticProps, its data is transferred to the standard output function of our front-end file, which displays our React page. We do all this to prevent code duplication and to ensure consistency in our data. What a mouthful, let’s start programming now.

The Helpers file

We start by creating the getTaxiData function in lib/helpers.js:

export async function getTaxiData(){
    let data = await fetch("https://api.data.gov.sg/v1/transport/taxi-availability").then(r => r.json())
    return {taxis: data.features.properties[0].taxi_count, updatedAt: data.features.properties[0].timestamp}
}

The API file

We then build in the handler function api/index.js as well as the import of the getTaxiData function:

import { getTaxiData } from '../../lib/helpers'
export default async function handler(req, res){
    res.status(200).json(await getTaxiData())
}

Here is nothing but SWR or ISR except the aforementioned project structure. The stuff starts now in index.js!

The front page file

The first thing we want to do is create our own getStaticProps function! This feature will introduce us getTaxiData function, use it and then send the data back with some additional configurations.

export async function getStaticProps(){
    const { getTaxiData } = require("../lib/helpers")
    return { props: (await getTaxiData()), revalidate: 1 }
}

I would like to focus on the revaluation key in our returned object. This key enables practically incremental static rebirth. It tells your host that every second that the static page recovers is an available option, that the option is then activated in the background when a customer visits your page. You can read more about Incremental Static Regeneration (ISR) here.

It’s now time to use SWR! Let’s enter it first:

import  useSWR from 'swr'

We are going to use SWR in our React rendering function, so let’s create the function:

export default function App(props){
}

We receive the props from getStaticProps. Now we are ready to set up SWR:

const fetcher = (...args) => fetch(...args).then(res => res.json())
const { data } = useSWR("/api", fetcher, {initialData: props, refreshInterval: 30000})

Let’s break it up. First, we define the fetcher. This is required by SWR as an argument so that it knows how to retrieve your data, as different frameworks, etc., may have different setups. In this case, I use the feature on the SWR document page. Then we call the useSWR hook, with three arguments: the way to retrieve data, the fetcher function and then an option object.

Therein options object, we specified two things:

  • the initial data
  • the interval at which SWR has to revalidate the data

The initial data option is where we provide the data we come from getStaticProps which ensures that data is visible from the beginning. Finally, we use the destruction of objects to get the data out of the hook.

To complete this, we provide the data with some basic JSX:

return <div>As of {data.updatedAt}, there are {data.taxis} taxis available in Singapore!</div>

And, we did it! There we have a lot of examples of using SWR with incremental static regeneration. (The source of our example is available here.)

If you ever come across old data with ISR, you know who to call: SWR.

Read more about SmashingMag

Smashing Editorial(vf, yk, hy)

[ad_2]

Source link