Using router inside getStaticProps

Viewed 8509

I'm trying to fetch data from an API that varies depending on the URL, trying to do it with withRouter but it seems it won't work inside getStaticProps.

I currently have the following code:

export async function getStaticProps({ router }) {
const pageRequest = `http://localhost:3000/api/posts/${router.query.pid}`
const res = await fetch(pageRequest)
const json = await res.json()
return {
    props: {
        json,
    },
}
}

It's returning:

TypeError: Cannot read property 'query' of undefined

What's the proper way to get the variable in the URL to use inside getStaticProps?

2 Answers

getStaticProps is called at build time. You don't have router because there is no request performed.

If the dynamic page looks like /pages/[pid].js you can access pid in context.params.pid.

export async function getStaticProps(context) {
  const pid = context.params.pid
  return {
    props: {}, // will be passed to the page component as props
  }
}

Note that using static export with dynamic routes requires getStaticPaths. You'd need to specify all possible IDs upfront, so Next.js knows what pages to generate.

export async function getStaticPaths() {
  return {
    paths: [
      { params: { pid: '1' } },
      { params: { pid: '2' } }
    ],
    fallback: true or false // See the "fallback" section below
  };
}

Also, you can't call your own API in getStaticProps as it's executed at build time (no server is running). You can fetch data directly from the database without an API call.

I would suggest to read Next.js Data fetching for more examples and details.

Alternatively, you can fetch the data on the client side instead.

Fetching data on the client side

getStaticProps

I'm not sure if this will work for your situation but if you use can getServerSideProps instead, you can get the query id with the following:

export async function getServerSideProps({ query }) {
  const pageRequest = `http://localhost:3000/api/posts/${query.pid}`
  const res = await fetch(pageRequest)
  const json = await res.json()

  return {
    props: {
        json,
    },
  }
}

I know that there are different considerations for using either getStaticProps or getServerSideProps but as described by Nikolai in his answer there are many more steps needed to work with getStaticProps in this situation.

Related