如何在SAP Spartacus中覆盖CMS驱动的预置页面路由?
查阅Spartacus官方路由链接自定义相关文档可知,官方原生仅支持修改产品页、分类页、品牌页的路由,文档有两点明确说明:
内容页面的URL可在CMS中配置
新增路由仅需在CMS中添加新的内容页面并设置页面标签即可
但Spartacus本身预置了一批内容页面(例如orders订单页),这类页面已经绑定了默认路由,实际开发中会出现自定义路由不生效的问题:当前自定义我的账户页路由为/account,但默认orders订单页路由仍指向/my-account/orders,需要可行方案覆盖Spartacus预置CMS页面的默认路由。
已在CMS中创建绑定自定义路由的新内容页面,配置如下:
;;orders ;/account/orders ;Orders History ;AccountPageTemplate
同时在前端侧尝试两种自定义路由配置方式,访问对应路径时都会因找不到匹配映射自动跳转至根路径/,两种配置分别为:
- 第一种配置
orders: { paths: ['account/orders'], }
- 第二种配置
{ data: { pageLabel: 'orders', cxRoute: 'orders' }, component: CmsPageComponent, canActivate: [CmsPageGuard], path: null }
问题核心原因是Spartacus预置的CMS页面路由硬编码在默认路由配置项中,单独给子路由设置全路径会因为父级路由前缀冲突、配置优先级不足导致匹配失败,两种可直接落地的方案如下:
方案一:全链路替换父子路由路径(推荐,无额外侵入性)
直接在根模块的路由配置中,同步修改父级账户路由和子级订单页路由的路径,显式关闭配置保护强制覆盖默认值,代码如下:
ConfigModule.withConfig({ routing: { routes: { // 替换父级my-account路由前缀为自定义的account myAccount: { paths: ['account'] }, // 子级orders路径配置为相对路径,不要带父级前缀 orders: { paths: ['orders'], // 强制允许覆盖默认预置配置,该参数必须加 protected: false } } } })
配置后最终订单页的完整路径就是/account/orders,和需求完全一致。
方案二:手动移除默认路由再注册自定义路由(适合不想改父级路由的场景)
如果不需要修改my-account父级路径,只想单独调整orders页面的路由,直接在AppModule构造函数中注入路由相关服务,手动清理默认配置后注册自定义路由即可:
// 先引入需要的依赖 import { RoutingConfigService } from '@spartacus/core'; import { CmsPageComponent, CmsPageGuard } from '@spartacus/storefront'; @NgModule({ // ... 原有模块配置 }) export class AppModule { constructor( private routingConfigService: RoutingConfigService, private router: Router ) { // 清空默认的orders路由配置 this.routingConfigService.setRouteConfig('orders', null); // 插入自定义路由,注意要放在路由配置数组最前面保证优先级 this.router.config.unshift({ path: 'account/orders', component: CmsPageComponent, canActivate: [CmsPageGuard], data: { pageLabel: 'orders', cxRoute: 'orders' } }); } }
注意:CMS端不需要重复创建label为
orders的页面,保留原有页面即可,重复创建同label页面会触发匹配冲突,反而导致路由跳转异常。
配置完成后清空本地构建缓存、重启开发服务,访问/account/orders即可正常加载订单历史页面,不会再自动跳转根路径。
内容的提问来源于stack exchange,提问作者nannnes

