最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Next.js: one page that match root '' and dynamic route 'param' - Stack Overflow

programmeradmin7浏览0评论

I have a website as a single page that is using Next.js. I have the home page on route / that show a list of products. The code of this page is located in pages/index.js. Each product has an id so I can jump to it using /#product-id.

To make it more url friendly I replicate this behaviour using the product-id as a second param in the route like that: /product-id.

What I do is simply looking on the product-id param using useRouter():

const selectedProductId = useRouter().query['product-id']

And then scroll to the element with this id using js:

document.getElementById(selectedProductId ).scrollIntoView()

So I to change my script name from /pages/index.js to /pages/[product-id].js.

So now the route /1234 work has expected but if I go to / I get error 404.

So has someone an idea how I can match / and /param using one js file?

I have a website as a single page that is using Next.js. I have the home page on route / that show a list of products. The code of this page is located in pages/index.js. Each product has an id so I can jump to it using /#product-id.

To make it more url friendly I replicate this behaviour using the product-id as a second param in the route like that: /product-id.

What I do is simply looking on the product-id param using useRouter():

const selectedProductId = useRouter().query['product-id']

And then scroll to the element with this id using js:

document.getElementById(selectedProductId ).scrollIntoView()

So I to change my script name from /pages/index.js to /pages/[product-id].js.

So now the route /1234 work has expected but if I go to / I get error 404.

So has someone an idea how I can match / and /param using one js file?

Share Improve this question edited May 31, 2020 at 8:56 Nikolai Kiselev 6,6132 gold badges32 silver badges39 bronze badges asked May 30, 2020 at 8:54 johannchopinjohannchopin 14.9k11 gold badges62 silver badges121 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

Optional catch all routes

Catch all routes can be made optional by including the parameter in double brackets ([[...slug]]).

Nextjs has file system based routing, so if you remove /pages/index.js of course you will get an 404 error. Also /pages/index.js and /pages/[product-id].js will render two separate pages.

To answer your question, if it is possible to match two routes like / and /[productId] in one file using nextjs I don't think that is possible however similar results can be achieved by using shallow routing specific to your use case.

So for your use case, I suggest using shallow routing unless you want to render the same ponent in both pages just to get the product-id or want to make use of hash URLs.

You can make product-id a query string parameter and update it using shallow-routing. Here is an example,

Keep /pages/index.js

import { useRouter } from 'next/router';

const router = useRouter()

// when want to change the productId call
router.push('/?productId=1234', undefined, { shallow: true })

// call the scrollToView inside a useEffect hook
useEffect(() => {
    const productId = router.query.productId
    // get the element using the productId above then call scrollIntoView()
})

// if using useEffect with the dependency router.query.productId, 
// when you change the productId once and scroll up and try to change to the same -
// productId again it will not scroll to view, hence not using the dependency array
// at all

To explain more on what shallow routing does

Shallow routing will allow the change of URL without running the data fetching methods i.e getStaticProps or getServerSideProps again. Which will make the updated query and pathname available without changing the state. Read more about it nextjs docs.

Option 1: Extract the shared code

You could extract a Page ponent to a separate file and then import it in both /pages/index.js and /pages/[product-id].js, so the code is not duplicated.

Option 2: Use experimental rewrites feature

Assuming you have /pages/[product-id].js you can show this page when a user requests /.

You would need to add next.config.js.

module.exports = {
  experimental: {
    async rewrites() {
      return [
        { source: "/", destination: "/[product-id]" },
      ];
    }
  }
}

So, when a user requests / they would see the content of /[product-id], just with the empty product id.

Note, that at the moment rewrite doesn't support auto-rendered dynamic pages, so you have to disable auto-rendering for the dynamic page.

You can do that by adding getServerSideProps to /pages/[product-id].js.

export async function getServerSideProps() {
  return {
    props: {},
  }
}
发布评论

评论列表(0)

  1. 暂无评论