具有下一个导出模式的动态路由
Posted
技术标签:
【中文标题】具有下一个导出模式的动态路由【英文标题】:Dynamic routing with next export mode 【发布时间】:2021-08-02 02:37:33 【问题描述】:我们在 next export mode 中使用 Next.Js(静态 html 导出),我们需要高级动态路由。
我们的路线看起来像/[config1]/[config2]/[optionalConfig?]/page
,其中一个段是可选的,并且页面名称是固定的。例如a/b/c/page1
或a1/b1/page2
。页面需要配置段数据来渲染。
我还没有找到任何使用built-in routing 的方法。我可以做/pages/[config1]/[config2]/page1.tsx
,但那个可选部分似乎是个问题。请注意,自定义服务器似乎不是一个选项,因为由于其他限制,我们必须使用下一个导出模式。
注意:我们不知道构建时的路径;它们代表了我们运行时配置的一部分。这必须使用客户端路由。 (我们确实知道有限的页面集 - 例如 page1 ... page10 - 但到这些页面的路径会有所不同。)
我尝试切换到 React Router,设置 useFileSystemPublicRoutes: false
并将路由添加到 pages/_app.tsx
(自定义应用程序)。这几乎有效,但我在控制台中看到on-demand-entries-utils.js
的许多 404 以及一些“检测到可能的 EventEmitter 内存泄漏”警告(在开发模式下)。
有效的解决方案(必须 100% 在客户端工作):
使用内置路由的方法 将 React Router 与 Next.Js 集成的示例 替代库(我查看过 next-routes,但已 3 年未更新)更新
我们或许能够消除对可选细分的要求。但是,看来我们必须实现getStaticPaths
并指定所有路由。例如:
pages/[config]/foo.tsx
export async function getStaticPaths()
// Runs at build time
return
paths: [ params: config: 'xyz' ],
fallback: false,
;
export async function getStaticProps(context)
return
props: ,
;
export default function FooPage(): JSX.Element
return <div>FOO</div>;
这会生成
┌ ○ / ├ /_app ├ ● /[配置]/foo ├ └ /xyz/foo问题在于我们在构建时不知道配置。
我们需要动态的客户端路由。我们希望继续使用 Next.js,因为最终我们也许可以使用 s-s-r,但目前还没有选择。
【问题讨论】:
我建议查看内置的optional catch all routes。 @juliomalves Catch-all 仅适用于页面名称,不适用于目录名称。我可能会制作一个包罗万象的页面,然后根据查询对象有条件地渲染组件“页面”,但这似乎是一种 hack。 它将为您在getStaticPaths
中定义的任何路径生成页面。您只需要确保getStaticProps
在生成这些页面时正确处理参数(由getStaticPaths
传递)。
@juliomalves 我们在构建时不知道路径。
让我们continue this discussion in chat。
【参考方案1】:
您可以创建一个包罗万象的路由来获取参数,包括可选参数,然后您需要根据该参数渲染正确的组件。所以如果你创建了:
pages/[...config].tsx
这与:
pages/[...config]/index.tsx
然后在index.tsx
中,您可以根据url 将配置作为getStaticProps
中的字符串数组获取。所以/config1/config2/optional
是[config1, config2, optional]
而/config1/config2
是[config1, config2]
。
因此,如果您需要在已知和可选路径下添加其他子页面,您可以将其用作各种目录路径。
【讨论】:
不幸的是,我了解到动态路由不适用于静态 HTML 导出,除非您在构建时预定义路径 - 我们不知道这一点。我已更新问题以反映这一点。 那么您只有三个选项 - 1) 使您所说的那些页面服务器端呈现不是一个选项,2) 将您的应用程序的该部分分离成一个单独的单页应用程序,例如创建反应应用程序和反应路由器(不理想),或 3)使用 url 参数而不是 url 路径 - myapp.com/?config1=foo&config2=bar 等,然后在 ping 服务器旁边的useEffect
中读取这些参数。我们在电子商务网站上执行此操作以获取订单历史记录。用户不在乎 - 只是我们开发人员讨厌它。
听起来 2 是我们唯一的选择 - 我们的利益相关者不会接受其他选项。谢谢。
这很糟糕,因为它绝对是最劳动密集型的,而且可能是最容易出现错误和集成问题的一种。如果可能的话,我肯定会提倡 #1 或 #3,但祝你好运!
我想你用你的三个选项搞定了。我们与 Vercel 的某个人确认,这不适用于下一次导出。将 React Router 放在自定义 404 页面中适用于选项 2,但它是一个 hack。 github.com/brajevicm/next-universal-route#readme 是一个可能。以上是关于具有下一个导出模式的动态路由的主要内容,如果未能解决你的问题,请参考以下文章