Nextjs dynamic routes with static pages gives `paths` must be an array of strings or objects...error

Viewed 2494

I've been following official Next.js guide (Nextjs - Dynamic Routes) for statically generated pages with dynamic routes. But I cannot generate pages with fetched data. I get the error below:

Error: Invalid paths value returned from getStaticProps in /posts/[id]. paths must be an array of strings or objects of shape { params: [key: string]: string }

[id].js

import { getAllPostIds, getPostData } from '../../lib/posts'
export default function Post({ postData }) {
  return (
    <Layout>
      <h1>Post Page</h1>
      {postData.id}
    </Layout>
  )
}

export async function getStaticPaths() {
  const paths = getAllPostIds()
  return {
    paths,
    fallback: false
  }
}

export async function getStaticProps({ params }) {
  const postData = getPostData(params.id)
  return {
    props: {
      postData
    }
  }
}

posts.js

In the code below, to makes things simple, I hardcoded fetch data from API to test my code.

import axios from 'axios'

export async function getAllPostIds() {
  const res = await axios('http://localhost:8000/api/posts/id=1')
  const posts = await res.data.results
  return posts.map(post => {
    return {
      params: {
        id: post.id
      }
    }
  })
}

export function getPostData(id) {
  return {
    id,
  }
}

If I log what I get from getAllPostIds() with the code below, I get [ { params: { id: '1' } } ]. Which seems exactly the same as the example in the official docs. But this gives me the error I mentioned in the beginning. But if I hardcoded my logged result, it works perfectly. I just don't know how to make this work with fetched API data.

Logging what getAllPostIds() returns ([ { params: { id: '1' } } ])

export async function getStaticPaths() {
  const paths = getAllPostIds()
  paths.then(data => console.log(data))
  return {
    paths,
    fallback: false
  }
}

Hardcoding getAllPostIds()'s return. Works perfectly. No error.

export async function getStaticPaths() {
  const paths = getAllPostIds()
  return {
    paths: [{
      params: {
        id: '1'
      }
    }],
    fallback: false
  }
}
1 Answers
export async function getStaticPaths() {
    const paths = getAllPostIds()
    paths.then(data=>console.log(data))
    return {
      paths,
      fallback: false
    }
  }

you call path.then to log the data. Does getAllPostIds() return a Promise? When I check the function it does not seem so, but if you return a promise you have to await the whole call before passing the data. Otherwise you pass the unresolved promise.

So just await the call like this:

export async function getStaticPaths() {
    const paths = await getAllPostIds()

    return {
      paths,
      fallback: false
    }
  }
Related