如何用ExpressJS创建层级不固定的电商SEO友好路由?
ExpressJS 实现电商多级分类与产品的SEO友好路由方案
一、搞定可变层级的路由实现
因为分类层级不固定,不能写死/catalog/c1/c2这种固定层数的路由,得用Express的灵活匹配机制来处理,同时要区分分类页和产品页的路由(产品页是分类路径后面多了个产品名)。
1. 两种实用路由写法
写法一:通配符+后端拆路径
注意:产品路由要放在分类路由前面,不然产品请求会被分类路由先接住。
// 匹配产品页:/catalog/任意层级分类/产品名 app.get('/catalog/*/:productName', async (req, res) => { // 拿到分类部分的路径,比如 "category1/category2/category3" const categoryPathStr = req.params[0]; const productSlug = req.params.productName; // 把分类路径拆成数组,方便查数据库:['category1', 'category2', 'category3'] const categorySlugs = categoryPathStr ? categoryPathStr.split('/') : []; // 这里根据分类slug数组和产品slug查数据库,返回产品页 // 示例:const product = await Product.findOne({ slug: productSlug, categoryPath: categorySlugs }); res.render('product', { product }); }); // 匹配分类页:/catalog/任意层级分类 app.get('/catalog/*', async (req, res) => { const categoryPathStr = req.params[0]; const categorySlugs = categoryPathStr ? categoryPathStr.split('/') : []; // 根据分类slug数组查对应的分类(比如从根到子的层级匹配) // 示例:const category = await Category.findOne({ slugPath: categorySlugs }); res.render('category', { category }); }); // 匹配根分类页:/catalog app.get('/catalog', async (req, res) => { // 返回所有一级分类的列表页 res.render('catalog-root'); });
写法二:正则路由更精准
如果要限制slug只能是字母、数字和短横线(避免非法路径),可以用正则来匹配:
// 用正则匹配多级分类+产品名的格式 app.get(/^\/catalog\/(([\w-]+\/)*)?([\w-]+)$/, async (req, res) => { const matches = req.path.match(/^\/catalog\/(([\w-]+\/)*)?([\w-]+)$/); // 处理分类部分的路径,去掉末尾的斜杠 const categoryPathStr = matches[1] ? matches[1].slice(0, -1) : ''; const lastSegment = matches[3]; // 先查是不是产品 const product = await Product.findOne({ slug: lastSegment, categoryPath: categoryPathStr.split('/') }); if (product) { return res.render('product', { product }); } // 不是产品就查分类 const categorySlugs = categoryPathStr ? [...categoryPathStr.split('/'), lastSegment] : [lastSegment]; const category = await Category.findOne({ slugPath: categorySlugs }); if (category) { return res.render('category', { category }); } // 都没找到返回404 res.status(404).render('404'); });
2. 数据库要这么配合
为了查询高效,给分类和产品表加个专门的字段存完整路径:
- 分类表:加
slugPath字段,比如根分类category1存['category1'],子分类category2(属于category1)存['category1', 'category2'],以此类推。 - 产品表:加
categoryPath字段,存所属分类的完整slug数组,比如['category1', 'category2', 'category3'],同时存产品自己的slug。
这样查的时候直接用数组匹配,比逐层查父分类快多了。
二、这个路由方案对SEO友好吗?
非常适合SEO,原因:
- 路径语义化:用户和搜索引擎一看路径就知道页面是啥层级的分类/产品,逻辑清晰。
- 关键词权重:路径里包含分类和产品的关键词,能提升相关词的排名。
- 避免重复内容:每个分类/产品对应唯一URL,不会出现多个URL指向同一页面的问题(只要你后端逻辑保证唯一性)。
额外SEO小技巧
- 加canonical标签:每个页面只留一个权威URL,防止搜索引擎认为是重复内容。
- 做面包屑导航:根据路由的分类层级生成面包屑,用户好导航,搜索引擎也能理清页面结构。
- 页面缓存:用Redis之类的缓存分类和产品页,提升加载速度,这也是SEO的重要指标。
- 动态meta标签:每个页面的title、description要根据内容生成,包含相关关键词。
内容的提问来源于stack exchange,提问作者Lukkyz
相关产品推荐
相关产品推荐

