Vue.js’s method of achieving seo: 1. Use SSR server rendering; 2. When [Nuxt.js] executes generate static packaging, dynamic routing is required to generate static pages first; 3. Pre-rendering [ prerender-spa-plugin]; 4. Use Phantomjs to process crawlers.
【Recommended related articles: vue.js】
How to do seo with vue.js:
1. SSR server rendering
About the server Rendering: According to the Vue official website, there are requirements for the Vue version and certain requirements for the server. It needs to support the nodejs environment.
The trade-offs of using SSR:
Limited by development conditions, browser-specific code can only be used in certain lifecycle hook functions (lifecycle hook) ; Some external libraries (external libraries) may require special processing to run in server rendering applications;
The environment and deployment requirements are higher and require a Node.js server running environment;
In case of high traffic, please prepare the server load accordingly and adopt caching strategy wisely.
Advantages:
Better SEO, since search engine crawlers can view fully rendered pages directly;
Faster time-to-content, especially for slow network conditions or slow devices.
Shortcomings: (pits encountered during development)
1. One set of code and two sets of execution environments will cause various problems, such as no window on the server side, document object, the processing method is to add judgment. If it is a client, it will be executed:
if(process.browser){ console.log(window); }
Reference npm package, with dom operation, for example: wowjs, you cannot use the import method, use:
if (process.browser) { var { WOW } = require('wowjs'); require('wowjs/css/libs/animate.css'); }
2.Nuxt asyncData method, get data before initializing the page, but only for page component calls:
// 并发加载多个接口: async asyncData ({ app, query }) { let [resA, resB, resC] = await Promise.all([ app.$axios.get('/api/a'), app.$axios.get('/api/b'), app.$axios.get('/api/c'), ]) return { dataA: resA.data, dataB: resB.data, dataC: resC.data, } }
Get parameters in asyncData:
1. Get dynamic routing parameters, such as :
/list/:id' ==> '/list/123
Receive:
async asyncData ({ app, query }) { console.log(app.context.params.id) //123 }
2. Get url? Get parameters , such as:
/list?id=123
Receive:
async asyncData ({ app, query }) { console.log(query.id) //123 }
3. If you use v-if syntax, deploy it online You may also encounter this error:
Error while initializing app DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
at Object.We [as appendChild]
According to issue 1552 on github nuxt, v-if should be changed to v-show syntax.
4. There are too many pitfalls. Leave them behind and update them later.
2. Static
When Nuxt.js executes generate static packaging, dynamic routing will be ignored.
-| pages/ ---| index.vue ---| users/ -----| _id.vue
If you need dynamic routing to generate a static page first, you need to specify the value of the dynamic routing parameter and configure it in the routes array.
// nuxt.config.js module.exports = { generate: { routes: [ '/users/1', '/users/2', '/users/3' ] } }
Run the package and you can see the packaged page.
But what should be done if the value of the routing dynamic parameter is dynamic rather than fixed?
Use a function that returns a Promise object type;
Use a function whose callback is callback(err, params).
// nuxt.config.js import axios from 'axios' export default { generate: { routes: function () { return axios.get('https://my-api/users') .then((res) => { return res.data.map((user) => { return { route: '/users/' + user.id, payload: user } }) }) } } }
Now we can access the payload from /users/_id.vue, as shown below:
async asyncData ({ params, error, payload }) { if (payload) return { user: payload } else return { user: await backend.fetchUser(params.id) } }
If your dynamic routing has many parameters, such as product details, it may be as high as several thousand. Ten thousand. An interface is needed to return all IDs, and then the IDs are traversed during packaging and packaged locally. If a product is modified or removed from the shelves, it must be repackaged. Packaging is also very slow and unrealistic when the quantity is large.
Advantages:
Pure static files, access speed is super fast;
Compared with SSR, it does not involve server load Question;
Static web pages are not suitable for hacker attacks and are more secure.
Insufficiency:
Not applicable if there are many dynamic routing parameters.
3. Prerender prerender-spa-plugin
If you only use it to improve the SEO of a few marketing pages (such as /, /about, /contact, etc.), Then you may need to pre-render. Instead of using a web server to dynamically compile HTML in real time, pre-rendering simply generates static HTML files for specific routes at build time. The advantage is that setting up prerendering is simpler and allows you to treat your frontend as a completely static site.
$ cnpm install prerender-spa-plugin --save
vue cli 3 vue.config.js configuration:
const PrerenderSPAPlugin = require('prerender-spa-plugin'); const Renderer = PrerenderSPAPlugin.PuppeteerRenderer; 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'), // 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。 routes: ['/', '/product','/about'], // 这个很重要,如果没有配置这段,也不会进行预编译 renderer: new Renderer({ inject: { foo: 'bar' }, headless: false, // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。 renderAfterDocumentEvent: 'render-event' }) }), ], }; } }
Add in main.js:
new Vue({ router, render: h => h(App), mounted () { document.dispatchEvent(new Event('render-event')) } }).$mount('#app')
Note: mode: "history" must be set in the router.
You can see the file after packaging, and package the folder /index.html, for example: about => about/index.html, which contains html content.
Advantages:
The changes are small, just introduce a plug-in and it’s done;
Disadvantages:
Dynamic routing cannot be used;
is only applicable to projects with a small number of pages. When there are hundreds of pages, packaging will be very slow;
4、使用Phantomjs针对爬虫做处理
Phantomjs是一个基于webkit内核的无头浏览器,即没有UI界面,即它就是一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现。
虽然“PhantomJS宣布终止开发”,但是已经满足对Vue的SEO处理。
这种解决方案其实是一种旁路机制,原理就是通过Nginx配置, 判断访问的来源UA是否是爬虫访问,如果是则将搜索引擎的爬虫请求转发到一个node server,再通过PhantomJS来解析完整的HTML,返回给爬虫。
具体代码戳这里: vue-seo-phantomjs
。
要安装全局 phantomjs ,局部 express ,测试:
$ phantomjs spider.js 'https://www.baidu.com'
如果见到在命令行里出现了一推html,那恭喜你,你已经征服PhantomJS啦。
启动之后或者用postman在请求头增加 User-Agent 值为 Baiduspider ,效果一样的。
部署上线
线上要安装 node 、 pm2 、 phantomjs ,nginx相关配置:
upstream spider_server { server localhost:3000; } server { listen 80; server_name example.com; location / { proxy_set_header Host $host:$proxy_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; if ($http_user_agent ~* "Baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|bingbot|Sosospider|Sogou Pic Spider|Googlebot|360Spider") { proxy_pass http://spider_server; } } }
优势:
完全不用改动项目代码,按原本的SPA开发即可,对比开发SSR成本小不要太多;
对已用SPA开发完成的项目,这是不二之选。
不足:
部署需要node服务器支持;
爬虫访问比网页访问要慢一些,因为定时要定时资源加载完成才返回给爬虫;
如果被恶意模拟百度爬虫大量循环爬取,会造成服务器负载方面问题,解决方法是判断访问的IP,是否是百度官方爬虫的IP。
总结
如果构建大型网站,如商城类,别犹豫,直接上SSR服务器渲染,当然也有相应的坑等你,社区较成熟,英文好点,一切问题都迎刃而解。
如果只是个人博客、公司官网这类,其余三种都可以。
如果对已用SPA开发完成的项目进行SEO优化,而且支持node服务器,请使用 Phantomjs 。
很少写文章,这是我这个月对Vue SEO方案的探索,写的不对的地方请指出,谢谢理解~
相关免费学习推荐:javascript(视频)
The above is the detailed content of How vue.js does SEO. For more information, please follow other related articles on the PHP Chinese website!