提到vue的seo优化,这本身就是一个麻烦,spa单页面应用对于网络爬虫是不友好的。
由于单页面,所以每个页面的title和meta标签都是一样的,右键点击查看网页源文件。
是看不到页面的dom结构的,包括meta和title的更改,这就不利于网络爬虫的爬取。
不过vue也提供了对于网页预渲染的一些解决方案,提高网站的seo的优化
本文只提供vue-cli3的解决方案
使用 webpack + prerender-spa-plugin + vue-meta-info轻松地添加预渲染
这里因为prerender-spa-plugin安装时候特别大,所以建议先安装淘宝镜像
使用cnpm
或者使用
---npm install npm install prerender-spa-plugin --save --ignore-scripts(没试验)
---npm install prerender-spa-plugin --save
vue.config.js
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
// eslint-disable-next-line no-unused-vars
const webpack = require('webpack')
const path = require('path')
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV !== 'production') return
return {
plugins: [
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 下面这句话非常重要!!!
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname, 'dist'),
// outputDir: path.join(__dirname, './'),
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
routes: ['/', '/exam', '/examInfor', '/courseInfor', '/shore', '/testData', '/overYear', '/freeLesson', '/getPull', '/contact'],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
})
]
}
},
}
main.js
new Vue({
router,
store,
render: h => h(App),
//添加到这里,这里的render-event和vue.config.js里面的renderAfterDocumentEvent配置名称一致
mounted () {
document.dispatchEvent(new Event('render-event'))
}
}).$mount('#app')
设置好之后,去router.js里面把mode改为'history',hash模式会打包的时候生成同样的页面,所以一定要history
然后就是npm run build打包,这样dist的文件夹目录结构就会变成如下的样子
就是打包之后,每个路由都会打包成一个文件夹,然后里面是index.html
遇到的问题
1.就是放到线上之后,会发现能正常运行,但是做了优化的页面刷新之后会没有样式,或者空白页面回到首页
造成问题的原因就是打包的时候vue.config.js的资源路径配置不对
没有优化之前的路径是
// 资源路径
publicPath: './',
打包之后路由下面的资源路径是这样的
解决办法
优化之后的路径是
// 资源路径
publicPath: '/',
打包之后的路由下面的资源路径是这样的
就是路径前面多了一个/
然后打包上传到服务器,再路由加载的时候刷新页面,页面就能正常的出来了!
但是还有一个就是刷新页面之后链接的后面会跟一个/
这个问题我现在还没做,等明天做了再更新下文章
然后就是为这些打包的静态页面分配title和meta标签,需要用到 vue-meta-info
安装
npm install vue-meta-info --save
main.js里面引入vue-meta-info
import MetaInfo from 'vue-meta-info'
Vue.use(MetaInfo)
这样在组件页面中就可以使用了
假设你要给hello.vue添加title,meta标签
hello.vue
<template>
...
</template>
<script>
export default {
metaInfo: {
title: '我是hello头', // set a title
meta: [{ // set meta
name: 'keyWords',
content: '我是hello关键字'
},
{
name: 'description',
content: '我是hello描述'
}]
//这里的link我没搞懂是什么意思,看官方文档也没找到具体的描述,可以不设置,注释掉
link: [{ // set link
rel: 'asstes',
href: 'https://assets-cdn.github.com/'
}]
}
}
</script>
这样再结合prerender-spa-plugin,打包之后,在dist文件夹找到hello文件夹下的index.html
打开你会发现就有title和meta的关键字和描述标签了
发布到线上之后,在页面右键---查看源代码---就可以看到页面的title和meta标签了
更新1:
有人问打包上线之后刷新页面链接后面会跟一个斜杠,这个对项目没什么影响,只是不美观。这个暂时我这边没有好的解决办法。期待后续探索吧
更新2:
prerender-spa-plugin和vue-meta-info只是对静态页面的处理,比如动态加载head中的meta标签和title这个暂时是不支持,建议使用基于vue.js的通用框架nuxt,nuxt是支持静态和动态服务端渲染的一个即插即用框架,现在项目转移到nuxt了,请看下篇文章《nuxt基于vuejs的seo动静态优化》
这里的每个路由都可以有title和meta的切换,是prerender-spa-plugin和webpack和vue-meta-info结合的结晶,后续有问题会继续更新