Static Site Generation with Next.js and TypeScript (Part II) - Fetching Data with getStaticProps

Responses (0)

Clap
4|0|

Disclaimer - Please read the first part of this blog post here before proceeding. It provides an overview of the Next.js application that's being built throughout this tutorial series, and it introduces developers to the Next.js framework. If you just want to jump straight into this tutorial, then clone the project repository and install the dependencies.

A major feature of the Next.js framework is the number of rendering strategies it supports:

  • Server-Side Rendering (SSR)

  • Static-Site Generation (SSG)

  • Incremental Static Regeneration (ISR)

  • Client-Side Rendering (CSR)

Each of these rendering strategies uses a different technique for data-fetching that's required for dynamically rendered content. For example, on the client-side, upon mounting a function component, you can call the useEffect hook to perform side effects. such as data-fetching, and update the UI accordingly. Alternatively, you can use a React hook library called SWR that's built specifically for data-fetching. In Next.js, data-fetching for the other browserless rendering strategies involves exporting specific functions within a page component's file:

Rendering StrategyExported FunctionDescription
Server-Side RenderinggetServerSidePropsOn each incoming request, Next.js runs getServerSideProps. Any data fetched inside of getServerSideProps can be passed to the page component as props. Then, using the data from these props, Next.js pre-renders the page.
Static-Site GenerationgetStaticPropsAt build time, Next.js runs getStaticProps. Any data fetched inside of getStaticProps can be passed to the page component as props. Then, using the data from these props, Next.js pre-renders the page.
Static-Site GenerationgetStaticPathsCan only be exported for pages of dynamic routes. These pages must also export getStaticProps. Unlike getStaticPaths, this function determines the list of paths that must be statically generated by Next.js. The pages for these paths are pre-rendered.
Incremental Static RegenerationgetStaticPropsAt build time, Next.js runs getStaticProps, just like for static-site generation. However, adding the revalidate prop to getStaticProps tells Next.js to re-run getStaticProps every x seconds and update the contents of a static page with new props without having to rebuild the entire Next.js application.

Below, I'm going to show you how to fetch data from an API with getStaticProps.

Installation and Setup#

To get started, clone the project repository and install the dependencies.

If you're coming from first part of this tutorial series, then you can continue on from where the first part left off.

Obtaining an Access Token for the Petfinder API#

Currently, the home page lacks a grid of cards that allow users to navigate to different pet animal listings.

Therefore, we need to send a request to the Petfinder API to fetch a list of pet animal types. For the home page to be pre-rendered with the grid of cards, this data must be fetched within an exported getStaticProps function in pages/index.tsx. If this data is fetched from within a useEffect hook, then the home page will only be able to render the grid of cards on the client-side, not at build time.

Let's export a getStaticProps function and annotate it with the GetStaticProps type, which will be imported from next. Since getStaticProps will fetch data, the function must be defined as an async function. Since data that's returned from this function gets passed as props to the page component, we need this function to return the fetched pet animal types (types). For now, we will return an empty array for types.

(pages/index.tsx)

To fetch any data from the Petfinder API, you must first authenticate your application and obtain an access token. Anytime data needs to be fetched from the Petfinder API, this access token must be added to the request's Authorization header.

To obtain an access token, we send a POST request to https://api.petfinder.com/v2/oauth2/token. This request must be sent with the following payload:

Your application's Petfinder client ID and secret should already be stored as environment variables (NEXT_PUBLIC_PETFINDER_CLIENT_ID and NEXT_PUBLIC_PETFINDER_CLIENT_SECRET respectively). If your application does not have a Petfinder client ID and secret, then visit the Petfinder developers portal and register for a developer account.

Upon sending a request to the POST /oauth2/token endpoint, a successful response should contain the following:

Note: expires_in represents an expiration duration in seconds. This means that one hour after receiving the access token, the access token will expire, and you will need to obtain a new access token to continue fetching data from the Petfinder API. We will handle token expiration in a later part of this tutorial series.

Let's obtain an access token within the getStaticProps function, like so:

(pages/index.tsx)

Fetching a List of Pet Animal Types#

After obtaining an access token for the Petfinder API, let's send a GET request to https://api.petfinder.com/v2/types to fetch a list of pet animal types, like so:

Now let's verify that the home page displays a grid of cards. Spin up the application in development mode:

Within a browser, visit localhost:3000.

If you hover over the Browse Listings links, you will notice that they all point to the same route: /types. To fix this problem, we must add an id property to each pet animal type. The id property should be a unique identifier that will be used as a...

  • Key for React to identify each item in the grid.

  • Route parameter for the "Browse Listings" URL (replaces :type in /types/:type).

Reload the page. Now the links point to the correct URLs.

Let's verify that the grid is pre-rendered by Next.js at build time. Run the build script to generate an optimized version of the application that's production-ready.

If you check the contents of the generated index.html file under the .next/server/pages directory, then you will notice that the grid has been pre-rendered by Next.js.

You can also verify that Next.js has pre-rendered the grid by spinning up the application in production mode, which will serve the statically generated pages:

If you open up the network tab of the developer tools and inspect the response for / (index.html), then you will notice that the page has already been pre-rendered prior to reaching the client's browser.

Another problem that you might have noticed is how slow the images load since they are high resolution images directly downloaded from Unsplash. We will address this in the next part of this tutorial series.

Next Steps#

If you find yourself stuck at any point during this tutorial, then feel free to check out the project's repository for this part of the tutorial here.

Proceed to the next part of this tutorial series to learn how to improve image loading with BlurHash.

If you want to learn more advanced techniques with TypeScript, React and Next.js, then check out our Fullstack React with TypeScript Masterclass:

Sources#


Clap
4|0