Weekend by the way to have done a good static page of the webApp project to do SEO optimization, because do not want to write lame SSR code, so ready to use pre-rendering, originally thought there are so many pre-rendering online articles, just find a follow do not finish, the young I paid the whole weekend….. This article will record the final configuration of T.T.

Statement:

  1. The following configurations are reserved only when necessary
  2. Generate directory is used herebaseInstead, please modify
  3. Vue-cli template is usedwebpackAnd other templates and so on
  4. WebApp – Online preview
  5. Github – Pre-rendered demo configured

If you are interested, you can join the wechat group at the end of the article and discuss with us

1. Introduction and application scenarios

We know that SPA has many advantages, but one drawback is that SEO is not friendly to stupid (not Google) search engines. To take care of these engines, there are currently two main solutions: Server Side Rendering and Prerending.

If you only need to improve SEO on a few pages (e.g. /, /about, /contact, etc.), then you may need to pre-render. Instead of using a Web server to dynamically compile HTML in real time (server-side rendering, SSR), you use pre-rendering to simply generate static HTML files for specific routes at build time. It mainly uses prerender-SPa-plugin, which, like SSR, can speed up page loading and is less intrusive. It can easily introduce pre-rendering mechanism with minor changes to an existing project, whereas SSR requires the entire project structure to be overthrown.

Access to pre-rendered pages is as fast as SSR, and it brings the server’s HTML compilation time up to build time, thus reducing the server’s stress. If your server has a 1M1G1 core small pipe server (poor) like mine, then pre-rendering may be more suitable for you. However, there are obvious differences between SSR and pre-rendered scenarios. Pre-rendered usage scenarios are more simple static pages. Server-side rendering is suitable for complex, large, and frequent interaction with server-side functional sites, such as e-commerce sites.

2. Install and configure

Let’s start with the stacks: VUE ^2.5.2, VUe-Router ^3.0.1, VUE-CLI ^2.9.6, webpack^3.6.0, prerender-SPa-plugin ^3.3.0

2.1 installation

The installation is the same as the other libraries

# Yarn
$ yarn add prerender-spa-plugin -D
# or NPM
$ npm install prerender-spa-plugin --save-dev
Copy the code

2.2 Front-end Configuration

First look at the file structure, using the webpack template generated by VUE-CLI2

│ ├─ Build │ build.js │ check-versions. Js │ utils ├─config │ dev.env.js │ index. Js │ ├─config │ dev.env.js │ index ├─ SRC │ ├─ SRC │ app.vue │ ├─ Assets │ ├─ Components │ ├─ Router │ ├─styles │ ├─utils │ ├ ─ ├ ─ bigdata.vue │ companyhonor.vueCopy the code

The router/index.js configuration requires histroy mode for pre-rendering. Some articles say that history mode is not required, which is wrong, otherwise the generated page will be the same HTML.

home
will redirect to localhost/home

// src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
 
 
Vue.use(Router)
 
 
export default new Router({
  mode: 'history'.base: '/base/'.routes: [...]. })Copy the code

And then config, notice that assetsPublicPath is not./,

// config/index.js

const path = require("path")
 
module.exports = {
  build: {
    index: path.resolve(__dirname, ".. /base/index.html"),
    assetsRoot: path.resolve(__dirname, ".."),
    assetsSubDirectory: "base/static".assetsPublicPath: "/",}}Copy the code

Then there is the plugin configuration, which is put in proD because it is only used in build

// build/webpack.prod.conf.js

const path = require('path')
const config = require('.. /config')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
 
const webpackConfig = merge(baseWebpackConfig, {
  new PrerenderSPAPlugin({
   staticDir: config.build.assetsRoot,
   outputDir: path.join(config.build.assetsRoot, 'base'),
   indexPath: config.build.index,
 
   // Path of the corresponding routing file
   routes: [
     '/'.'/BigData'.'/CompanyHonor'].renderer: new Renderer({
     headless: false.// If no, remove it
     renderAfterDocumentEvent: 'render-event'})})})Copy the code

Note that if your project is deployed on Linux /centOS without a desktop, you need to remove headless: false. If centOS does not find lib error, please refer to issue-200.

Also note the above a renderAfterDocumentEvent: ‘render – event’, this means in the render – prerender event event trigger after implementation, this event. We are in the main js trigger mounted in the hook

// src/main.js

import Vue from 'vue'
import App from './App'
 
new Vue({
  el: '#app'.render: h= > h(App),
  mounted() {
    document.dispatchEvent(new Event('render-event'))}})Copy the code

There is a configuration should pay attention to in the build/utils. Under ExtractTextPlugin in js. Extract publicPath, otherwise will find some of the references in the vue resources

// build/utils.js

ExtractTextPlugin.extract({
  use: loaders,
  fallback: 'vue-style-loader'.// publicPath: '.. /.. / '
})
Copy the code

NPM run build generates HTML for the page that was just configured on routes in PrerenderSPAPlugin, which will briefly open the Chromium browser.

The resulting directory tree:

│ index. The HTML ├ ─ BigData │ index. The HTML ├ ─ CompanyHonor │ index. The HTML └ ─ static ├ ─ CSS ├ ─ fonts ├ ─ img └ ─ jsCopy the code

Finally, if you want to further optimize the SEO generated pages, you can cooperate with vue-meta-info, which has a lot of articles on the web

2.3 nginx configuration

By the way, post the Nginx configuration

server {
        listen 80;
        server_name localhost;
        root /nginx-1.14.0/html;

        error_page 500 502 503 504 /50x.html;
        
        location ~ ^/base/ {
          try_files $uri $uri/ /base/index.html;
        }
        location = /50x.html {
            roothtml; }}Copy the code

Online posts are mostly different in depth, even some inconsistent, the following article is a summary of the learning process, if you find mistakes, welcome to comment out ~

Reference:

  1. Vue. Js server side rendering guide
  2. Vue server render & pre-render
  3. vue-cli v3, can’t get it to work.. issue #215
  4. unable to start Puppeteer. Failed to launch … issue #200
  5. When assetsPublicPath is set, the… issue #176
  6. Vue. js Vue-router history mode route, domain name secondary directory subdirectory nginx configuration
  7. Another approach to Meta SEO for Vue single pages

PS: Welcome to pay attention to my official account [front-end afternoon tea], come on together

In addition, you can join the “front-end afternoon tea Exchange Group” wechat group, long press to identify the following TWO-DIMENSIONAL code to add my friend, remarks add group, I pull you into the group ~