[英]Next.js: one page that match root '/' and dynamic route '/param'
I have a website as a single page that is using Next.js.我有一个使用 Next.js 的单页网站。 I have the home page on route
/
that show a list of products.我在 route
/
上有主页,显示产品列表。 The code of this page is located in pages/index.js
.该页面的代码位于
pages/index.js
中。 Each product has an id
so I can jump to it using /#product-id
.每个产品都有一个
id
,所以我可以使用/#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
.为了使它对 url 更友好,我使用
product-id
作为路径中的第二个参数来复制这种行为: /product-id
。
What I do is simply looking on the product-id
param using useRouter()
:我所做的只是使用
useRouter()
查看product-id
参数:
const selectedProductId = useRouter().query['product-id']
And then scroll to the element with this id using js
:然后使用
js
滚动到具有此 id 的元素:
document.getElementById(selectedProductId ).scrollIntoView()
So I to change my script name from /pages/index.js
to /pages/[product-id].js
.所以我将我的脚本名称从
/pages/index.js
为/pages/[product-id].js
。
So now the route /1234
work has expected but if I go to /
I get error 404.所以现在路线
/1234
工作已经预料到,但如果我 go 到/
我得到错误 404。
So has someone an idea how I can match /
and /param
using one js
file?那么有人知道如何使用一个
js
文件匹配/
和/param
吗?
Nextjs has file system based routing, so if you remove /pages/index.js
of course you will get an 404
error. Nextjs 有基于文件系统的路由,所以如果你删除
/pages/index.js
当然你会得到一个404
错误。 Also /pages/index.js
and /pages/[product-id].js
will render two separate pages.此外
/pages/index.js
和/pages/[product-id].js
将呈现两个单独的页面。
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.要回答您的问题,如果可以使用 nextjs 在一个文件中匹配
/
和/[productId]
之类的两条路由,我认为这是不可能的,但是通过使用特定于您的用例的浅层路由可以实现类似的结果。
So for your use case, I suggest using shallow routing unless you want to render the same component in both pages just to get the product-id
or want to make use of hash URLs.因此,对于您的用例,我建议使用浅层路由,除非您想在两个页面中呈现相同的组件只是为了获取
product-id
或想要使用 hash URL。
You can make product-id
a query string parameter and update it using shallow-routing.您可以将
product-id
查询字符串参数并使用浅路由对其进行更新。 Here is an example,这是一个例子,
Keep /pages/index.js
保留
/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
Shallow routing will allow the change of URL without running the data fetching methods ie getStaticProps
or getServerSideProps
again.浅层路由将允许更改 URL 而无需再次运行数据获取方法,即
getStaticProps
或getServerSideProps
。 Which will make the updated query and pathname available without changing the state.这将使更新的查询和路径名可用,而无需更改 state。 Read more about it nextjs docs .
阅读更多关于它的 nextjs 文档。
You could extract a Page component to a separate file and then import it in both /pages/index.js
and /pages/[product-id].js
, so the code is not duplicated.您可以将 Page 组件提取到单独的文件中,然后将其同时导入
/pages/index.js
和/pages/[product-id].js
,因此代码不会重复。
rewrites
featurerewrites
功能Assuming you have /pages/[product-id].js
you can show this page when a user requests /
.假设您有
/pages/[product-id].js
您可以在用户请求/
时显示此页面。
You would need to add next.config.js
.您需要添加
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.因此,当用户请求
/
他们会看到/[product-id]
的内容,只是带有空的产品 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 .请注意,目前 rewrite 不支持自动渲染动态页面,因此您必须禁用动态页面的自动渲染。
You can do that by adding getServerSideProps
to /pages/[product-id].js
.您可以通过将
getServerSideProps
添加到/pages/[product-id].js
来做到这一点。
export async function getServerSideProps() {
return {
props: {},
}
}
Optional catch all routes可选捕获所有路线
Catch all routes can be made optional by including the parameter in double brackets ([[...slug]]).通过将参数包含在双括号 ([[...slug]]) 中,可以使捕获所有路由成为可选的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.