next.js: unexpected params in getStaticProps

Bug report

Describe the bug

I’m getting unexpected or undocumented results for getStaticProps with a dynamic route parameter. The params slug is an array of path parts (looks like path.split('/')). It occurs for me when the page is in a dynamic folder and named index.js and not with a spread filename ie [...slug].js. Here’s an example:

Problem case:

// at pages/abc/[slug]/index.js
export async function getStaticProps({ params }) {
  console.log(params); // --- @build: { slug: 'a' } @runtime: { slug: ['abc', 'a'] }
}

What I expected:

// at pages/abc/[slug]/index.js
export async function getStaticProps({ params }) {
  console.log(params); // { slug: 'some-slug' }
}

I get these errors at runtime after deploying to now serverless. Builds are successful and the page appears to work but found the error in the now function logs.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 6
  • Comments: 33 (11 by maintainers)

Most upvoted comments

For anyone else stumbling on this, I wrote this ugly fix that seems to catch the edge cases I’ve hit so far:

const cleanNextParams = (queryParams: string[]) => {
  let params = [...queryParams]

  // Sort out next params
  if (params.includes("_next")) {
    const indexOfNext = params.findIndex((e) => e === "_next")
    params.splice(indexOfNext, 3)
  }

  // remove .json from params
  params = params.map((p) => p.replace(".json", ""))

  return params
}

export const getStaticParam = (queryParam: string | string[], path: string, param: string) => {
  if (typeof queryParam === "string") {
    return queryParam
  }

  const indexOfParam = path.split("/").findIndex((el) => el === param)

  if (indexOfParam < 0) {
    return null
  }

  const cleanedParams = cleanNextParams(queryParam)

  return cleanedParams[indexOfParam]
}

// pages/blog/[article].ts
export const getStaticProps = ({params}) => {
   const path = "/blog/[article]"
   const articleId = getStaticParam(params.article, path, "[article]")
}