admin管理员组

文章数量:1336304

I'm migrating a site over from Gatsby using WP as a headless CMS. I didn't build the original site so I'm inheriting a load of code I'm not familiar with.

I'm using a /pages/listing/[slug].js ponent to generate individual listings for this client. I am fetching paths by querying all the slugs for their listings in getStaticPaths, and using the slug to query the db to get data for the page using getStaticProps. All good so far. Only issue right now is I've been told the client wants to retain their urls as they currently are - eg listing/experience/location/product-name-here (where product-name-here is the slug I fetched from the CMS), but I have only figured out how to do listing/product-name-here.

My failed approaches so far have been to:

  • Change the ponent to [...slug].js, but I am getting moaned at for the slug not being an array. Even if I change it into an array manually when I am fetching the static paths, because only the slug is being fetched, I am still not using the correct url.
  • Use the as prop on the Link ponent. It sends me to the link that I want now, but I get a 500 error. If I enter the url manually using the href prop (ie. listing/product-name-here), the page loads correctly, but with the wrong url.

I have wondered if there is some way to access the URL, but the only thing I have e across is so far is useRouter and since that's a hook I am unable to use it outside of the ponent itself.

I have left code snippets out because I feel like my approach is fundamentally wrong rather than this being an annoying error I am getting.

Edit The problem was eventually solved by having fallback set to true, and setting a hell of a lot of optional chaining for anything handling API related data - as well as empty defaults on all props. My gut feeling is still that this is not the correct 'Next' way to handle this, but the project was migrated over from Gatsby and kind of shoehorned in so I just needed to get it working.

I'm migrating a site over from Gatsby using WP as a headless CMS. I didn't build the original site so I'm inheriting a load of code I'm not familiar with.

I'm using a /pages/listing/[slug].js ponent to generate individual listings for this client. I am fetching paths by querying all the slugs for their listings in getStaticPaths, and using the slug to query the db to get data for the page using getStaticProps. All good so far. Only issue right now is I've been told the client wants to retain their urls as they currently are - eg listing/experience/location/product-name-here (where product-name-here is the slug I fetched from the CMS), but I have only figured out how to do listing/product-name-here.

My failed approaches so far have been to:

  • Change the ponent to [...slug].js, but I am getting moaned at for the slug not being an array. Even if I change it into an array manually when I am fetching the static paths, because only the slug is being fetched, I am still not using the correct url.
  • Use the as prop on the Link ponent. It sends me to the link that I want now, but I get a 500 error. If I enter the url manually using the href prop (ie. listing/product-name-here), the page loads correctly, but with the wrong url.

I have wondered if there is some way to access the URL, but the only thing I have e across is so far is useRouter and since that's a hook I am unable to use it outside of the ponent itself.

I have left code snippets out because I feel like my approach is fundamentally wrong rather than this being an annoying error I am getting.

Edit The problem was eventually solved by having fallback set to true, and setting a hell of a lot of optional chaining for anything handling API related data - as well as empty defaults on all props. My gut feeling is still that this is not the correct 'Next' way to handle this, but the project was migrated over from Gatsby and kind of shoehorned in so I just needed to get it working.

Share Improve this question edited Dec 6, 2024 at 18:21 desertnaut 60.4k32 gold badges155 silver badges181 bronze badges asked Jun 27, 2021 at 3:08 kmarskmars 1643 silver badges13 bronze badges 2
  • You need to create a file: ./pages/listing/experience/location/[slug].js , basically directories inside directory. Please refer: Nested Routes – brc-dd Commented Jun 27, 2021 at 8:48
  • @brc-dd thanks for the ment, but this is not what I'm going for. I did actually find a way to get the paths from the CMS, and getStaticPaths is getting the array of values to create the route for the catch all [...slug].js, but getStaticProps is not seeing the params.slug being passed to it. So I can't query the db for the page content I need. – kmars Commented Jun 27, 2021 at 20:41
Add a ment  | 

3 Answers 3

Reset to default 5

Use pages/listing/[...slug].js as filename, and then return from the getStaticPaths an object like this:

  return {
    paths: [
      { params: { slug: ["path1"] } },
      { params: { slug: ["path2"] } },
      { params: { slug: ["deeper", "path"] } }
    ],
    fallback: false
  };

This means that following addresses are working:

  • listing/path1
  • listing/path2
  • listing/deeper/path

Then you can access the slug as an array in getStaticProps from the context context.params.slug. That would contain ["path1"], ["path2"] or ["deeper", "path"] depending on the page visited.

You can try it out in the sandbox below:

https://codesandbox.io/s/confident-microservice-lu2jl?file=/pages/listing/%5B...slug%5D.js

Update: Next 13+

if you are using an App router then getStaticPaths is replaced with generateStaticParams.

here is how it looks like,

export async function generateStaticParams() {
  return [{ slug: ['1'] }, { slug: ['2', '3'] }]
}

for more check out next js doc

Try out this tool! https://www.npmjs./package/next-list

It’s easy: just run npm run list, and it will list all your pages and API routes, distinguishing whether they’re dynamic, server, client, etc.!

本文标签: javascriptNextjs catchallas routingStack Overflow