Taha
Taha

Reputation: 396

How do getStaticPaths and getStaticProps work together?

I have read the Next.js docs, and I know how to work with both getStaticProps and getStaticPaths.

What I'm missing is how they actually work together? I mean when exactly getStaticProps is called (when used with getStaticPaths in a [slug].js file) ?

In my analysis (which I'm not sure of), I think getStaticProps is "some how" called inside the loop of getStaticPaths, so getStaticPaths runs getStaticProps for every object in its "paths" variable, am I right?

Look for my comment in this code snippet:

export async function getStaticPaths() {
  // Call an external API endpoint to get posts
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
// getStaticProps is called somewhere in the previous loop???

  
  return { paths, fallback: false }
}

export async function getStaticProps({ params }) {
  // params contains the post `id`.
  // If the route is like /posts/1, then params.id is 1
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // Pass post data to the page via props
  return { props: { post } }
}

export default Post

I also want to confirm another understanding, does getStaticPaths modify the context variable by assigning the params key for each object in the paths array, so when it calls getStaticProps the params will be updated in the context (which both functions have access to) and ready for getStaticProps?

I read the Next.js docs and watched many videos about data fetching in Next.js, but still didn't find the answer to my questions.

Thanks, Taha

Upvotes: 10

Views: 3630

Answers (1)

Svish
Svish

Reputation: 157991

getStaticPaths is called first. You return some options and an array of parameters to feed into getStaticProps.

getStaticProps is then called once for each set of parameters you returned from getStaticPaths. This step happens in parallel as well, to speed up the build.


Re "what if you have an extreme amount of paths":

If you return a million values from getStaticPaths, then yes, getStaticProps will be called a million times. And yes, that could be very intensive, which is why you in getStaticPaths also have the fallback property that you can return.

With that you can say what should happen if a client requests a path that has not been pre-rendered, and only return the subset of your paths that you do want pre-rendered. Could for example be your top 100 blog posts, top 1000 products based on latest analytics, or even an empty list, if you don't want to pre-render anything.

Your fallback options are fallback: true and fallback: 'blocking'. The first results in Next serving your page fallback-page with router.isFallback set to true, while it's generating the missing page (so you then have to deal with that, show a spinner or whatever). And the second, which is much easier, and better for the user as long as your rendering isn't insanely slow (in my opinion), just means that Next will block the response until the rendering is done, and then return the page normally. So in short true means you have to implement a spinner (maybe good for super slow pages?), and 'blocking' means you do not (my preferred one).

See https://nextjs.org/docs/api-reference/data-fetching/get-static-paths for more info.

Upvotes: 14

Related Questions