Rya*_*ley 9 umbraco url-routing server-side-rendering nuxt.js headless-cms
我正在尝试使用 CMS 定义的路由来获取内容,这些内容用于确定在我们的 Nuxt 前端加载哪个页面。那么,您如何实现自己的逻辑来将路由连接到内容,将内容连接到页面,同时保持 Nuxt 页面的所有出色功能?
任何帮助将不胜感激!
Headless CMS 正在兴起,我们希望在通用模式 (SSR) 下将我们的 CMS 与 Nuxt 一起使用。
我们一直在使用 Umbraco(一种免费托管的 CMS),它具有灵活的路由系统,我们无法在没有大量用户强烈反对的情况下对其进行限制。
注意:Umbraco 不是无头的,我们自己在 GitHub 上的Umbraco Headrest 项目中添加了该功能
注意:每条内容都有一个包含其内容类型名称的字段
例如,以下内容结构是有效的。
.
home
??? events
| ??? event-one
| ??? event-two
| ??? event-special-offer
| ??? some-other-content
??? special-offer
??? other-special-offer
Run Code Online (Sandbox Code Playgroud)
因此,如果我们想用 nuxt 呈现这些特价商品,我们将需要使用 Pages/SpecialOffer.vue。
问题是这些特价商品的默认路径是:
/special-offer/other-special-offer/events/event-two/event-special-offer编辑器还可以创建自定义路径,例如:
/holiday2020/special(可以指向event-special-offer)编辑器还可以重命名内容,因此other-special-offer可以变成new-special-offer. 然后一把umbraco将返回new-special-offer两个/other-special-offer和/new-special-offer。
以下方法很有希望,但要么不起作用,要么只是部分成功。
我们尝试创建对 CMS 的 API 的异步调用,然后使用响应来确定要加载的页面。
中间件.js
.
home
??? events
| ??? event-one
| ??? event-two
| ??? event-special-offer
| ??? some-other-content
??? special-offer
??? other-special-offer
Run Code Online (Sandbox Code Playgroud)
在服务器上运行时,中间件好像在路由解析后运行,导致如下错误:
vue.runtime.esm.js?2b0e:619 [Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
Run Code Online (Sandbox Code Playgroud)
注意:第一次访问时,中间件只运行在服务器端,后续访问时,中间件只运行在客户端。
由于插件在生命周期的早期运行,我们认为我们会在那里尝试相同的方法并尝试调用 CMS 的 API 并根据结果确定要加载的组件。
插件.js
export default function (context) {
return new Promise((resolve, reject) => {
/**
* Prepend the cms provided url's path with /content,
* which the API knows is for CMS content
*/
context.app.$axios.$get(`/content${context.route.path}`)
.then((content) => {
// Save the resulting content to vuex
context.store.commit('umbraco/load', content)
const { routes } = context.app.router.options
/**
* The content has a contentType property which is a string
* containing the name of the component we want to load
*
* This finds the corresponding route
*/
const wantedRoute = routes.find(x => x.name === content.contentType)
// Sets the component to load as /Pages/[componentName].vue
context.route.matched[0].components = {
default: wantedRoute.component
}
resolve()
})
})
Run Code Online (Sandbox Code Playgroud)
注意:插件在第一次访问时在服务器和客户端上运行。在后续访问中,它们仅在客户端上运行。
不幸的是,这也不起作用,因为app.router.beforeEach()不允许异步代码。因此,API 请求从未得到解决。
生成路线图列表工作正常,除非您在构建后更改路线。这里的问题是您无法在运行时更新路由,因此在 CMS 中重命名或添加新内容不会在 Nuxt 中镜像。
这种方法似乎是我们问题的默认解决方案,涉及在 Nuxt 中使用单个 Page 调用 API 然后动态加载组件。不幸的是,这种方法删除了 Nuxt 的大部分页面特定功能(例如页面转换)。
失去这些功能真的很不幸,因为 Nuxt 非常好,我们希望尽可能多地使用它!
我们尝试的是使用一个通用页面模板来处理所有可能的路线,代码可以在以下位置找到: https: //github.com/dpc-sdp/ripple/blob/v1.23.1/packages/ripple-nuxt-tide/ lib/module.js#L208
该单页模板将匹配*用户要求的路线。但是,如果您愿意,您可以为多个路由规则定义多个模板。
Nuxt应用程序和CMS API之间的通信如下:
Nuxt:CMS您好,用户想要路径的数据/about-us。
CMS:明白了。让我检查 CMS 数据库,并找到相同的 url。如果有的话,我会把数据发回给你,否则我会给你一个404。
这样您就不会失去页面转换功能。在该 Nuxt 页面模板中,您可以向 CMS 发送请求并获取页面数据。这可以在 Nuxt 路由器中间件或页面异步数据中完成,现在也许fetchhook 是最好的地方。我不确定哪个是最好的,我们正在使用异步数据,这可能不是最佳实践。
| 归档时间: |
|
| 查看次数: |
796 次 |
| 最近记录: |