前言
最近写了个门户网站使用vue做的,不可避免的遇到了SEO方面相关的问题,下面将我采用的解决方案贴出来供大家参考
主流的方案
1.SSR服务器渲染;
2.静态化;
3.Nuxt;
4.预渲染prerender-spa-plugin;
第一点推荐先去官网了解清楚一下,这里不是使用的这个方案。我的是已经完成的vue应用,再去采用SSR方案就有点不太现实了,如果非要使用SSR的话,建议在着手开发之前,就了解清楚。
第二点静态化,直接放弃。手写静态代码太难受了。
第三点prerender-spa-plugin是主要的插件,再搭配几个其他的插件一起可以达到比较好的效果。
方案内容
1.prerender-spa-plugin
这个插件是模拟浏览器访问站点将站点内容以静态文件方式保存。
运行流程为:
读取配置,获取需要预渲染的页面-->模拟浏览器打开页面-->页面脚本触发渲染时机-->渲染出当前页面内容-->获取当前所有的dom结构-->生成HTML文件
npm i prerender-spa-plugin
2.sitemap-webpack-plugin
这个插件是生成站点地图的,在各大搜索引擎中会要你提交站点地图文件以供它来收录你的站点。
npm i sitemap-webpack-plugin
3.vue-meta-info
这个插件是动态配制内容展示页中的<title>标签、keywords关键字、description描述内容的。
npm i vue-meta-info
详细配置
1.prerender-spa-plugin
我之前写过一篇文章,点击查看
2.sitemap-webpack-plugin
build目录下webpack.prod.conf.js文件中引入:
const SitemapPlugin = require('sitemap-webpack-plugin').default;
build目录下webpack.prod.conf.js文件中加入:
//生成sitemapconst routesList = ['/', '/', '/bbb', '/ccc', '/ddd', '/eee', '/fff', '/ggg', '/hhh', '/mm', '/mm/kk', '/ll/dd'];
build目录下webpack.prod.conf.js文件中plugins节点下:
new SitemapPlugin('http://www.xxxx.com', routesList, { fileName: 'sitemap.xml', lastMod: true, changeFreq: 'monthly' }),
至此配置完成。成功运行后会在你指定的打包输出目录中生成sitemap.xml文件与sitemap.xml.gz文件。
3.vue-meta-info
src目录下main.js文件中引入:
//seo优化import MetaInfo from 'vue-meta-info'Vue.use(MetaInfo)
src目录下新建vue-meta-info.js(注意是与main.js同级):
;var metaInfo = { index: { title: '这是页面标题内容index', meta: [{ name: 'keywords', content: '这是关键字,以,分隔,一般不超过100个字符' }, { name: 'description', content: '这是描述一般不超过200个字符' } ] }, home: { title: '这是页面标题内容home', meta: [{ name: 'keywords', content: '这是关键字,以,分隔,一般不超过100个字符' }, { name: 'description', content: '这是描述一般不超过200个字符' } ] },};if (window) window.$VueMetaInfo = metaInfo;export default metaInfo;
src目录下main.js文件中导入:
import VueMetaInfo from '@/vue-meta-info.js';Vue.prototype.$VueMetaInfo = VueMetaInfo;
views目录中任意页面中使用:
export default { metaInfo:window.$VueMetaInfo['index'], name: '', components: { }, props: { }, data() { return { } },}
或者这样使用:
export default { metaInfo: function() { return this.getMetaInfo }, computed: { getMetaInfo: function() { return this.$VueMetaInfo['index'] } }}
或者这样使用:
export default { metaInfo: { title: '标题', meta: [{ name: 'keywords', content: '关键字' }, { name: 'description', content: '内容' } ] }}
另外请注意在项目目录下index.html中检查并添加好以下项:
<meta data-vue-meta-info="true" name="keywords" content="关键字"><meta data-vue-meta-info="true" name="description" content="内容"><title>标题</title>
至此配置完成。
其他注意事项
1.百度收录这边比较坑,需要注意几点:
a.注册百度ssp媒体管理服务,在里面将你们公司的财务及相关信息完善好。
b.注册百度账号中心,将该账户的信息完善好,特别是实名认证等。
c.注册百度站点收录搜索资源平台,提交收录你们的网站。
2.搜狗站长平台
3.360站长平台
4.描述中不要使用敏感词汇。
5.建议加入百度统计,以便查看相关访问数据。
6.尽量不要使用动态跳转
//尽量不要使用这种方式进行路由跳转this.$router.push({ path: '/index'})
<!-- 建议使用这种方式进行路由跳转 --><router-link to="/index"> 返回首页</router-link>
7.小站点能邀请其他网站将本站地址加入友情链接最好。
<!-- 没有互为友情连接的 增加 rel="nofollow" --><a target="_blank" rel="nofollow" href=""> 湘公网安备 00000000000000号</a><!-- --><a target="_blank" href="http://youqing.com/" title="友情网站"> 友情网站</a>
8.使用有语义的标签,而不是万物皆是<div>
<!-- 这点很重要,会影响搜索引擎对你的站点评估。作为一个前端开发人员更应该清楚这点,语义是方便搜索引擎了解标签的含义 --><h1>标题</h1><span>文本</span><p>段落</p>
9.补充很关键的一点
在编译之后dist中的目录结构:
一般在nginx中会指向到index.html,但是这会导致抓取问题(影响你网站收录),因为index.html是模板编译文件,你可以打开查看编译后的代码:
<!-- body中只包含以下内容外加script标签,它没有实际的内容主体 --><body> <div id="app"></div> <script type="text/javascript" src="/static/js/manifest.047100007cb87c4ab16f.js"></script> <script type="text/javascript" src="/static/js/vendor.74350d00003b4f02c74e.js"></script> <script type="text/javascript" src="/static/js/app.86573b8f0000647522c1.js"></script></body>
其他文件夹中的html文件是首先通过这个模板然后再载入自己的内容最后渲染出该页面实际的内容,换句话说,index文件夹中的内容才是你实际想要让搜索引擎抓取的内容。
所以最后你需要补充的一步是:
a.将index文件夹中的index.html替换掉最外层的index.html文件(我使用的是这种方案)
b.变更nginx指向(没实践过)
最后再贴出我的nginx配制:
# 仅供参考,请按照实际情况取舍。在实际项目中应用过,代码可用。server { listen 80; server_name server-web; # 打包好的dist目录文件,放置到这个目录下 root /Users/dlamliu/Public/web/server-web; location / { try_files $uri $uri @route; index index.html index.htm; } location @route { rewrite ^.*$ /index.html last; } # 我的请求代理,不会的话甩给后端,这里仅供参考 location /api { proxy_pass http://www.xxxx.com; proxy_set_header Host $http_host; proxy_method POST; proxy_connect_timeout 15; proxy_send_timeout 15; proxy_read_timeout 15; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }