The fallback Option

Learn what the fallback option of the getStaticPaths method does.

When learning to statically generate dynamic routes, we learned about the getStaticPaths() method and what it does. However, one thing that we missed was the fallback option that was returned from this method. Let’s take a look at what this option is, what values it can take, and what those values mean for the web page.

The fallback option

The fallback option can take one of three values:

  1. false: When fallback is set to false, the paths that aren’t returned by the getStaticPaths function are redirected to the default 404 page of Next.js. Recall that we used fallback: false in our categories page. This is because we passed the complete set of paths that the [category].js page could take.

  2. true: This is a very powerful functionality that Next.js provides for static generation. Setting the value of the fallback option to true results in a few things in our application:

    1. The paths that are returned by getStaticPaths are statically generated at build time.

    2. New paths won’t be redirected to the 404 page. On the first request, Next.js serves a fallback version and statically generates the page in the background. On every subsequent request for that page, the page generated on the first request is served as if it was pre-rendered during build time.

    3. If we use next/link or next/router to route to a page with fallback: true, it behaves like fallback: blocking and doesn’t serve a fallback version of the page.

  3. blocking: Setting fallback to blocking is similar to true, with a small difference. Instead of serving a fallback version of the page, the application waits for the page to be rendered on the server and then serves it. Similarly to fallback: true, the page is cached for future use.

Note: We won’t be using fallback: true for the context of this course, however it’s important to know what it does.

Using fallback: 'blocking'

We’ve already discussed what setting the fallback option to 'blocking' does. Now, it’s time to see that in action. We’ve already created a page that displays the meals of a category, so now we’re going to create a page that displays the details of a meal.

The problem that arises here is that we can’t fetch all the meals and return a list of their unique identifiers from the getStaticPaths function. This is where the fallback: 'blocking' option comes in. Let’s take a look at what it looks like:

Press + to interact
export async function getStaticPaths() {
return {
paths: [
{params: {
meal: '52772'
}},
{params: {
meal: '53050'
}},
],
fallback: 'blocking',
}
}

The paths array remains unaffected, because it’s independent of fallback. We need to remember that we’ll have to manually route to the 404 page if a user manually enters a URL that is not a part of our application. In other words, the entered URL won’t produce a result from our API.

Let’s take a look at how this would work in an actual application:

import { Grid, Card, Typography } from '@mui/material';
import React from 'react'
import Image from 'next/image';
import styles from '../styles/Home.module.css'
import { useRouter } from 'next/router';

const MealCard = (props) => {
    const {meals} = props
    const router = useRouter();

    return (
        <Grid container direction="row" alignItems="center" justifyContent="center" spacing={1} sx = {{flex: "wrap"}}>
        {
          meals.map((meal) => 
            <Grid item key={meal.idMeal} 
            onClick = {() => router.push(`/meals/${meal.idMeal}`)}
            >
              <Card variant='outlined' className={styles.card}>
                <Grid container direction='column' justifyContent='center' alignItems='center' >
                  <Grid item 
                    className={styles.imgContainer}
                  >
                    <Image 
                      src = {meal.strMealThumb} 
                      alt={meal.strMeal} 
                      layout="fill"
                      objectFit="cover"
                      quality={100}
                    />
                  </Grid>
                  <Grid item>
                    <Typography variant='body1'>
                      {meal.strMeal}
                    </Typography>
                  </Grid>
                </Grid>
              </Card>
            </Grid>
          )
        }
      </Grid>
    )
}

export default MealCard;
Using the fallback: 'blocking' option

In line 11 of the pages/meals/[meal].js file, we’ve manually routed to the ErrorPage that can be imported from next/error. Now, if we route to /meals/1, we’ll be redirected to the 404 page because there is no meal in our API database that has an ID of 1. Similarly, /meals/53050 will result in a meal page displaying “Ayam Percik,” a Malaysian chicken dish.