2

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 Answer 1

4
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
    }
  }
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! It worked! getAllPostIds() indeed returns Promise, that's why I logged with path.then. But I never tried to resolve promise. I wanted to keep things as original as possible based on the documentation. I thought Nextjs was handling some things "magically". Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.