uni-app ssr(服务器渲染) + 动态路由(伪静态) + seo优化

uni-app ssr(服务器渲染) + 动态路由(伪静态) + seo优化

uni-app主要用于小程序开发 也支持H5开发。由于使用的是vue单页面。所以想要搜索引擎seo优化的难度是相当大。uni-app只提供了一个托管云函数的ssr方式,作用相当有限。所以这个轮子必须得自己来造。

这些坑帮你们踩过了 不要去踩了。
1:ssr(服务器渲染) 只支持托管代码到uni-app云函数上。
2:路由是pages.json写死的单页面不支持伪静态
3:路由不能使用自己的vue-router@4
4:路由不能自行增加addRouters uni-app会去自己的对象检测路由是否存在。
5:哪怕检测路由你都绕过了 你会发现页面不会调用onLoad这些生命周期。当普通组件而不是页面级组件。而且ssr服务端也不支持。

1:解决动态路由:
就是一个页面组件 实现多个路径都可以访问。
比如/pages/index/id /id/:id 定义这样的动态高级路由。
有人会想到使用url参数不就可以了。
我的哥既然做seo优化。H5页面还在使用动态参数这样的动态路径。权重根本不高。
如果一个个的手动pages.json增加页面。那商城 文章这样的 怎么办。
所以要解决seo 必须要解决动态路由。

这条路坑很多。网上没有一个能用的。
都是解决路由守卫这些功能。并没有动态高级路由
但看都在说有个能用 但是价格有点小贵. 收费的。
因为这些我觉得我花时间研究uni-app源码自然可以解决。
最终功夫不负有心人找到了解决办法。

const hookRoute = (routes) => {
	if (!routes && typeof __uniRoutes !== 'undefined') routes = __uniRoutes
	if (!Array.isArray(routes)) return routes
	const needPush = []
	for (const route of routes) {
		let seoPath = route?.meta?.seoPath || seoRoutes[route.path];
		if (!seoPath) {
			if (!route.path || route.alias) continue;
			const seoPathSplit = route.path.split('/')
			seoPath = `/${seoPathSplit[seoPathSplit.length-1]}`
		}
		const newRoute = {}
		for (const k in route) newRoute[k] = route[k];
		newRoute.path = seoPath
		if (pathKeys[seoPath]) continue;
		pathKeys[seoPath] = newRoute
		needPush.push(pathKeys[seoPath])
	}
	routes.push(...needPush);
	return routes
}

就这么简单。路由就增加好了。

但新的问题来了。测试普通路由这样动态添加没问题。
但动态高级路由这样添加就有问题。

上面说过就算增加了路由又能怎样。
uni-app有判断路由是否存在。 像 /id/:id 这样的路由 怎么能通过判断呢。

使用:alias
动态变更这个alias就能通过uni-app判断路由是否存在。

那就使用uni.addInterceptor 拦截器拦截请求之前动态设置这个alias就实现。

function seoHook(path) {
	if (!path || typeof path !== 'string') return null
	path = path.split("?")[0];
	if (pathKeys[path]) return pathKeys[path]
	const hookData = matchPath(path, pathKeys);
	if (hookData) hookData.alias = path;
	return hookData
}

//该拦截器如果跟你的守卫有冲突 需要自行合并到你的守卫代码里 seoHook(args.url)
function addInterceptor() {
	// 要拦截的页面跳转方法列表
	const navigationMethods = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'];
	// 设置拦截器
	navigationMethods.forEach(method => {
		uni.addInterceptor(method, {
			invoke(args) {
				const seoHookData = seoHook(args.url);
				return true; // 允许跳转
			},
			fail(e) {
				console.error(e)
			}
		});
	});
}

测试通过一切正常

2:解决seo优化
这个简单直接在页面里增加即可

<page-meta>
   <head>
       <title>标题</title>
       <meta name="description" content="uniapp h5 seo搜索引擎优化 支持伪静态" />
       <meta name="keywords" content="uniapp seo,uniapp ssr,uniapp 伪静态" />
   </head>
</page-meta>

那么动态如何实现呢:

//uniapp_seo/pages/index/id.vue 具体看这个演示代码
export default {
            data() {
                const idData={
                    "1": {
                        "title": "这是文章1的标题 黑神话悟空",
                        "keywords": "这是文章1的关键词",
                        "description": "这是文章1的description",
                        "content": "文章1:黑神话悟空"
                    },
                    "2": {
                        "title": "这是文章2的标题 全红婵",
                        "keywords": "这是文章2的关键词",
                        "description": "这是文章2的description",
                        "content": "文章2:全红婵"
                    },
                    "default": {
                        "keywords": "这是默认的关键词",
                        "description": "这是默认的描述",
                        "content": "我是默认的内容"
                    }
                }
                return {
                    ...idData[this.$route?.params?.id||"default"]
                }
            }
}

需要注意写data函数里 其他地方ssr不会渲染。

我之前还说过如果是商城 文章系统上面这样的肯定无法满足了必须服务器上渲染了
这部分放文档里说。 太复杂不是好事。

3: 解决ssr(服务器渲染)
上一篇文章有详细的如何解决非托管使用uni-app的ssr。 这里不再多说。
可以看上一篇文章

最终打包全部源码开源给需要的人 不要再去踩坑造轮子。

uniapp-router-h5

仅支持uni-app Vue3项目 不支持Vue2 (因为uni-app vue2不支持ssr)

用途:

实现uni-app的h5项目的搜索引擎seo优化提高网站排名终极解决方案。

功能:

  1. uni-app h5项目(Vue3)动态路由 也就是伪静态路由(网上并没有相关的功能 据说有一家支持但收费)

  2. ssr(服务器渲染)将uni-app项目在服务器上转为静态页面并实现服务端的动态路由。

  3. 突破uni-app官方ssr必须托管代码并使用uniCloud(云函数)的限制 可以任何平台运行

  4. seo优化 支持每个页面设置meta 关键词 描述等 (动态路由设置页面关键词有单独的说明)

开始使用:

  1. 下载安装
git clone https://github.com/fzl51/uniapp-router-h5.git
cd uniapp-router-h5
npm install
  1. 运行
npm start

或者

node main.js

此时打开 http://localhost:8080 鼠标右键查看源码看seo效果
演示:https://v.yy2169.com

使用文档:

uniapp_seo目录

uni-app项目源码 里面是演示如何使用。

  1. 在main.js导入路由 会自动hook路由增加动态路由(伪静态)
//uniapp_seo/main.js
import './router'
  1. 配置路由方法1: uniapp_seo/router.js (推荐) 2选1
//uniapp_seo/router.js
const seoRoutes = {
    "/pages/index/id": "/id/:id"
}
  1. 配置路由方法2: 直接在pages.json 设置简单(微信小程序端会有提示 可以加条件编译)
{
    "path": "pages/index/seo",
    "style": {
      // #ifdef H5 
      "seoPath":"/seo/:name",
      // #endif 
      "navigationBarTitleText": "uni-app seo 动态路由 伪静态"
    }
}
  1. 路由格式:支持动态高级路由(伪静态) /id/:id 这种路径也支持 /h5 这样的静态路径


  2. seo优化 在页面级组件直接写下面代码即可
#uniapp_seo/pages/index/seo.vue
<page-meta>
   <head>
       <title>标题</title>
       <meta name="description" content="uniapp h5 seo搜索引擎优化 支持伪静态" />
       <meta name="keywords" content="uniapp seo,uniapp ssr,uniapp 伪静态" />
   </head>
</page-meta>
  1. 动态页面设置不同的meta关键词 页面数据等信息
//uniapp_seo/pages/index/id.vue 具体看这个演示代码
export default {
            data() {
                const idData={
                    "1": {
                        "title": "这是文章1的标题 黑神话悟空",
                        "keywords": "这是文章1的关键词",
                        "description": "这是文章1的description",
                        "content": "文章1:黑神话悟空"
                    },
                    "2": {
                        "title": "这是文章2的标题 全红婵",
                        "keywords": "这是文章2的关键词",
                        "description": "这是文章2的description",
                        "content": "文章2:全红婵"
                    },
                    "default": {
                        "keywords": "这是默认的关键词",
                        "description": "这是默认的描述",
                        "content": "我是默认的内容"
                    }
                }
                return {
                    ...idData[this.$route?.params?.id||"default"]
                }
            }
}
  1. 也可以在服务端写代码实现动态路由seo优化 我们演示项目在服务端实现的.
    为了减少复杂度我们删除了服务端实现部分代码
    不然一会uni-app项目设置一会在服务端代码设置 人都醉了。

    服务端设置动态路由seo 优点是每次更改不需要重新编译。
    注意:⚠️服务端实现seo优化就不要在页面组件实现
//routes.js
const meta={
    "/": {
        "keywords": "这是默认的关键词",
        "description": "这是默认的描述",
    },
    "/id/1": {
        "title": "这是文章1的标题 黑神话悟空",
        "keywords": "这是文章1的关键词",
        "description": "这是文章1的description",
    }
}
const head = meta["/id/1"];//  /id/1 根据请求页面动态获取
if (head) {
    let headStr = ''
    for (const key in head) {
     headStr += key==='title'?`<title>${head[key]}</title>\n`: `<meta name="${key}" content="${head[key]}">\n`
    }
    //finalHtml是routes.js文件里的
    if (headStr) finalHtml = finalHtml.replace(/(<head[^>]*>)(?!.*<head[^>]*>)/i, `$1\n${headStr}\n`);
}

8. uniapp-router-h5 使用了 uni.addInterceptor 拦截器。可以扩展实现路由前置守卫。
如果你也使用此拦截器造成冲突。可以将你的拦截器合并进了。也可以删除我们的拦截器 在你的代码里调用 seoHook(args.url);

uni-app HBuilder X设置

1.在uniapp设置路由mode: history

2.发布的时候设置ssr发行 (Vue3才支持)

web 目录

web是uniapp HBuilder X选择ssr发行H5项目后生成。直接复制到网站目录即可

ssr(服务器渲染)注意事项

  1. 不能有环境代码。详情可以看官方的说明 比如 window document
  2. 还有很多api不支持 比如 uni.getSystemInfoSync uni.createSelectorQuery uni.createAnimation
  3. 注意链接是否是onclik事件 需要使用navigator
  4. 如果有不兼容的代码 会node报错 不会服务器渲染 但不影响网页运行
  5. ssr很多代码不兼容 多到让你怀疑人生 做好心里准备。

github开源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值