背景
最近在开发前端项目时,公司为了提升搜索引擎排名,要求我们对网站做一些SEO优化手段,在与相关的搜索优化公司合作后,对方提出了诸如对关键页面加上H1标签、设置关键词TDK、为logo图设置alt等的建议。
但很多前端开发框架如vue,react等打包后页面的数据都放在了js代码中,只在页面js加载后才出现,这样将无法被搜索引擎识别到。
项目中用的也是vue,所以就需要有一个将js内容固化到HTML页面上的方案。
常见的SEO优化方案有页面预渲染和SSR,分别针对的场景也有所不同:
- SSR需要对原代码的结构、部署方式等做出比较大的变化,接入较为笨重,但能处理一些具有实时性的后端返回数据;
- 预渲染则与之相反,易接入、几乎不影响原代码,但只能处理页面内容不实时发生变更的情况。
在经过讨论后,因为目前的项目是一个部门的一个产品官网,并没有太多了后台数据交换。所以想着尽量从简,我选择了用预渲染来解决这个问题。
方案介绍(prerender-spa-plugin+vue-meta-info)
这里要介绍的是基于prerender-spa-plugin与vue-meta-info的一套官网前端SEO预渲染方案。
prerender-spa-plugin是一个webpack插件,其作用是将渲染的页面固化成HTML文件。原理是利用无头浏览器(puppeteer)遍历配置中的路由,在收到结束的事件时,将当时的页面数据输出成HTML文件。
vue-meta-info是一个能在vue中使用的工具,能在vue文件中动态更改当前页面的meta中的信息(例如title,description等)。
将二者结合,就可以做到动态渲染页面内容,并输出html文件。
方案实施
作为示范,将如下的一个vue页面输出预渲染页面。项目GitHub仓库:https://github.com/lwklwklwk/prerender-spa-plugin-vue-cli
上图的vue文件:
<template> <div class="app"> <h1>萝卜官网</h1> <p>这是某个需要预渲染的页面</p> <h2>SEO要点</h2> <p>h1标签是很重要的</p> <p>网站的子标题用h2标签也是需要的</p> <p>logo图片最好用img,其中的alt描述别漏了</p> <p>重要页面的TKD(title,keywords,description)一定要设置哦</p> <p>对出站链接设置nofollw标签,防止网站权重分散</p> <p>设置友链交互</p> <p>针对搜索引擎的sitemap文件的设置与提交</p> </div> </template> <script> export default { name: ‘app‘ } </script> <style lang="less"> body { background-color: #eee; font-family: Helvetica Neue, Helvetica, Arial, Microsoft YaHei, sans-serif; margin: 0; font-size: 18px; } .app { background-color: #fff; margin: 20px auto; padding: 24px 32px; width: 50vw; min-width: 652px; max-width: 1300px; } </style>
渲染出来的html文件:
可以看到里面没有任何的文件内容,无法完成我们的SEO要求。
为webpack加入如下如下配置后:
new PrerenderSPAPlugin({ // 生成文件的路径,也可以与webpakc打包的一致。 // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。 staticDir: path.join(__dirname,‘dist‘), // 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。 routes: [‘/‘], // 这个很重要,如果没有配置这段,也不会进行预编译 renderer: new Renderer({ inject: { foo: ‘bar‘ }, headless: false, // 在 main.js 中 document.dispatchEvent(new Event(‘render-event‘)),两者的事件名称要对应上。 renderAfterDocumentEvent: ‘render-event‘ }) })
再在main.js里加上触发事件:
new Vue({ render: (h) => h(App), mounted () { document.dispatchEvent(new Event(‘render-event‘)) // 触发 } }).$mount(‘#app‘)
再次build,结果是:
可以看到,内容已经被渲染上html文件中了。
vue-meta-info的使用方法
1.安装:
npm i vue-meta-info --save
2.使用:
在 main.js 文件中引入 vue-meta-info
import MetaInfo from ‘vue-meta-info‘;
Vue.use(MetaInfo)
3.设置:
export default { name: ‘app‘, metaInfo: { title: ‘萝卜官网‘, // set a title meta: [ { // set meta name: ‘keyWords‘, content: ‘关键词‘ }, { name: ‘description‘, content: ‘描述‘ } ] } }
可以看到此组件已经正常使用。
再打包看看效果:
完美~