Reference: SEO solution of SPA author: Shidong Ke

Recently, the department’s project has a demand for SEO optimization of the home page.

Requirement background: The main project of our group is front-end Vue+Element and back-end PHP+Yii. This project is not a completely separate project from the front and back ends; index.html is provided by the back end, which then references static resources generated by the front end project in index.html. In view of time cost and actual needs, the home page and several propaganda pages were reformed.

This paper is divided into three parts:

  • Why does SPA need SEO
  • Popular SEO solutions
  • Nuxt conducted SEO optimization on the homepage of Vue project

Why does SPA need SEO

SPA, which stands for Single Page Application, refers to a Single Page Application. SEO stands for Search Engine Optimization.

The code we typically produce with a front-end framework (Vue in this case) looks something like this:

<! DOCTYPEhtml>
<html>
<head>
  <meta charset="UTF-8">
  <title>title</title>
</head>
<body>
  <div id="app"></div>
  <script src="index.js"></script>
</body>
</html>
Copy the code

The actual display content of the page (what the user actually sees) is rendered by JS, so when the search engine crawler crawls our page, it also gets the above HTML code. Although we can add some description information by adding
tags in , it’s not enough, and the actual content we show is still not available to search engine crawlers, so SEO optimization is needed for the project.

Popular SEO solutions

SSR of SEO program

SSR, full name for server-side Render, refers to server-side rendering. The counterpart is CSR (client-side Render). SSR is a relatively primitive way of developing the front and back end. The basic idea is that when a user goes to the server to request a page, the back end retrieves data from the database, populates the data into a template provided by the front end, and returns a complete HTML. But now popular SSR concept and before is actually different. SSR is now primarily for acceleration (reduced white screen time) and SEO (search engine optimization). The basic principle is similar to before, but the template used by modern SSR is different from the simple HTML template before. It is generally developed and maintained by the front-end using Nodejs, which is closer to the process of browser rendering. Render the page on the back end and then return it to the browser.

SSR advantage

  1. SEO and SMO (Social Media Optimization is a set of methods for obtaining public communication through Social Media, online organizations, and community sites).

  2. Improved first screen rendering speed.

SSR disadvantage

  1. Additional development and maintenance costs. For example, SSR code does not use the API that exists on the client side but does not exist on the server side (window, document, life cycle call error (such as Vue mounted, etc.))
  2. Server development costs. At present, SSR is generally the work of the front end, but most of the front end does not have rich experience in server development, performance, cache strategy is not very good
  3. Server-side load

This means that the server side takes over some functions of the browser, which has some impact on the load on the server side.

Static SEO solutions

Unlike SSR, which outputs HTML in real time, statics renders the HTML before the user accesses it.

Static advantage

  1. HTML files can be rendered without extensive back-end development experience
  2. Static files have the advantages of SEO and fast first screen rendering

Static disadvantage

  1. SSR content is dynamic, and Prerender determines content at deployment time
  2. Related to the first point, SSR content can be related to users, and the content of all users is the same when static

Prerender for SEO solutions

Prerender, which means server pre-render, means prerender.io. The idea is to determine the source of the request on the server side and return it directly if it’s a user request, or hand it to Prerender if it’s a crawler from a search engine. Prerender uses a headless browser, simulates opening a SPA app, captures the JS rendered DOM and feeds it to a search engine to achieve a pseudo-SSR effect.

Prerender combines the advantages of both, being generic and suitable for most WEB SEO without invading code. However, due to development costs and requirements, we ended up with a static solution for Nuxt.

Nuxt conducted SEO optimization on the homepage of Vue project

About Nuxt. Js

Nuxt.js, a server rendering application framework based on vue.js. Support SSR and Prerender.

Nuxt.js integrates the following components/frameworks for developing complete and powerful Web applications:

  • Vue 2
  • Vue-Router
  • Vuex (introduced only when the Vuex state tree configuration item is configured)
  • Vue server-side rendering (excluding mode: ‘spa’)
  • Vue-Meta

In addition, Nuxt.js uses Webpack along with vue-Loader and Babel-Loader to handle automated build work of code (such as packaging, code layering, compression, and so on).

The purpose of using Nuxt.js this time is to optimize the homepage and publicity page for SEO. Considering the development cost and time cost, the static function of Nuxt (pre-rendering) is finally used to transform the project.

Specific steps

1. New projects

Because it was part of the project, a new project was created. CMD/winpty + NTPX. CMD/winpty + NTPX. CMD/winpty + NTPX. Execute the following code and select configuration items to install.

CMD create-nuxt-app nuxt-demo or winpty NPX. CMD create-nuxt-app nuxt-demoCopy the code

Here are the configuration items I selected:

Once the project is created, follow the instructions and try it out.

The newly created project directory looks like this:

  • Assets Static resources

  • Components in this folder do not need to be imported when they are used, as if they have been registered globally. These components cannot use asyncData.

  • The layouts are used to organize the layout component of an application, which I understand is similar to app.vue in the Vue project

  • Middlwware application middleware, this is not used

  • Node_modules depend on the package

  • On pages, nuxt. js framework reads all.vue files in this directory and automatically generates the corresponding route configuration. Using other types of files in this directory may cause an error when NPM run generate is generated

  • The plugins directory. Used to organize JavaScript plug-ins that need to run before the root vue.js application is instantiated. During the life of any Vue component, only the beforeCreate and Created methods are called on both the client and server side. Other lifecycle functions are called only on the client side.

  • Static Directory of static files. The static directory is used to store application static files. These files are not processed by nuxt.js calling Webpack for build and compilation. When the server starts, files in this directory are mapped to the root/of the application.

  • Store Vuex state tree. The nuxt.js framework integrates Vuex state tree configurations, which can be activated by creating an index.js file in the Store directory.

  • The nuxt.config.js file is used to organize the personalized configuration of the nuxt.js application to override the default configuration.

  • other

.babelrc,.editorConfig, package.json, package-lock.json, etc., have the same functions as files of the same name in other projects.

  • The alias

~ or @ => srcDir ~~ or @@ => rootDir

In the vue template, if you need to import assets or static directory, use~/assets/your_image.pngand~/static/your_image.pngWay.

2. Migrate files

Take the old project home page and pitch page code and dependent static files, as well as some ESLint configuration, WebPack configuration, etc., whatever you can use, then modify the reference path and remove the code you don’t need.

Here are the directories:

  • Assets Static resources such as CSS, icon, and Font

  • Components used on the home page and promotional page

  • layouts App.vue

  • Middlwware is not used

  • Node_modules depend on the package

  • Pages Pages to which the home page and promotional page refer.

  • Various plugins that plugins use.

    • Axios encapsulation (not using nuxt.js default @nuxtjs/axios)
    • elementUI
    • Other plug-ins used (Video, Zepto, etc.)
    • Utility functions (should be placed under assets)
  • The static. Ico file

  • Store VuEX related files

  • The nuxt.config.js file is used to organize the personalized configuration of the nuxt.js application to override the default configuration.

  • other

.babelrc,.editorConfig, package.json, package-lock.json, and so on.

3. Modify the configuration

This part is important, because many things in Nuxt are actually configured from the beginning, such as its directory structure, which is generally not recommended to change. If you want to modify the configuration, you must do so in nuxt.config.js. Nuxt has a lot of documentation on configuration, so here’s what I used.

inport webpack from 'webpack'
export default {
  ssr: false.// Whether to enable server rendering. The default value is false
  target: 'static'.// server: used for server-side rendering, static: used for static websites
  root: {
    base: '/page/' // The base URL of the application, if the entire application is provided under this path, root.base should be used. When used, access to the ***.com/home route should use ***.com/page/home
  },
  head: { // To import some static resources, fill in the header information
    title: 'nuxt-demo'.meta: [{charset: 'utf-8' },
      { name: 'viewport'.content: 'width=device-width, initial-scale=1' },
      { hid: ' '.name: 'description'.content: ' '}].script: [{src: 'https://cdn.bootcdn.net/ajax/libs/zepto/1.2.0/zepto.js'}},css: [ // Globally used CSS
    'element-ui/lib/theme-chalk/index.css'.'~/assets/css/common.css'.'~/assets/css/element-variables.scss',].plugins: [ // Use plugins
    {src: '~plugins/element-ui'},
    {
      src: '~plugins/log.js'.mode: 'client' // Client or server: The file is contained only on the client or server side. If the code uses the browser API such as Window or Document, the client can only be used
    },
    {
      src: '~plugins/route.js'.mode: 'client'}].components: true.// Automatically import components
  buildModules: [ // Some modules are required only during development and build. Using buildModules helps speed up production startup and greatly reduces the size of node_modules production deployments.
    '@nuxtjs/eslint-module'].build: { // Nuxt.js allows you to customize the webPack build configuration based on server requirements.
    transpile: [/^element-ui/].// Use Babel to convert to specific dependencies. It should be that element-UI uses ES6 syntax, so it needs to be transformed
    publicPath: ' '.// Static resource reference path (usually CND address)
    plugins: [ Nuxt uses an older version of WebPack and some new features are unavailable
      new webpack.DefinePlugin({
        __ENV__: JSON.stringify(process.env.ENV || 'dev'})]}}Copy the code

4. Project deployment

As this project shares a domain name with other projects: www.###.com, it is necessary to ensure that another project is also available. All projects with Nuxt at deployment time are placed under the directory www.###.com/page using Ng…

  • Add the location/Page configuration item to the server
  • Redirect the root path to www.### # page/home
  • Compatibility with existing access paths for older projects
  • Cross-jump between homepage project and old project (main site) (login and logout jump, etc.)

5. Frequently asked Questions

A, Document is not defined or window is not defined

Solution: This problem is caused by server rendering using A DOM-related API such as Window or Document. There are two common reasons:

  • Life cycle usage errors in pages, such as Windows in Created

Nuxt executes beforeCreate and Created in the Vue lifecycle on the server. If the DOM API is not available for these two lifecyres, build errors will be reported.

  • Third-party plug-ins use DOM-related apis such as Window or Document

Nuxt.js allows js plug-ins to be executed before the vue.js application is run. This is especially useful when you need to use your own libraries or third-party modules. Note, however, whether the plugin is required on both the client and server side, and whether the PLUGIN uses DOM-related apis (which can lead to build errors).

Solutions:

  • Using the life cycle correctly, only the beforeCreate and Created methods are called on the client and server side during the life cycle of any Vue component. Other lifecycle functions are called only on the client side.

The window or Document API is not available. It can be executed in Mounted.

  • When using third-party plug-ins:
plugins: [
  {
    src: '~plugins/log.js'.mode: 'client'}]Copy the code

Added mode: ‘client’ to enable third-party plugins to be used only during client rendering.

NuxtLink cannot open new pages

Nuxtjs provides
during route navigation, but there is a problem with this tag: the link cannot be opened in the new window. It is suggested to change the tag to A, which can not only meet the requirements, but also facilitate the search engine to climb the relevant link.

Register global methods

Sometimes we want to use functions or values throughout the project. In a Vue project it is possible to hang methods on Vue instances, but the official documentation makes it clear: Do not use vue.use () globally, Vue.component(), and do not insert anything in the Vue dedicated to Nuxt injection within this function. This will result in server-side memory leaks.

It also provides us with a method (inject(key, value)) to register global methods (variables) :

// plugins/hello.js
export default ({ app }, inject) => {
  // Inject $hello(msg) in Vue, context and store.
  inject('hello'.msg= > console.log(`Hello ${msg}! `))}Copy the code
// nuxt.config.js
export default {
  plugins: ['~/plugins/hello.js']}Copy the code

It can then be used in pages, components, and plug-ins.

// a.vue export default { mounted() { this.$hello('mounted') // will console.log 'Hello mounted! $hello('asyncData') {$hello('asyncData') // If using Nuxt <= 2.12, use 👇 app.$hello('asyncData')}}Copy the code

Nuxt supports adding head information to pages.

export default {
  data () {
    return{} }, created () {}, ... , head () {return {
      title: ' '.meta: [{hid: ' '.name: ' '.content: ' '}]}}}Copy the code

Nuxt.js automatically generates the route configuration of vue-Router module according to the pages directory structure.

  • Based on the routing
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
Copy the code

So nuxt.js automatically generates the following route configuration:

router: {
  routes: [{name: 'index'.path: '/'.component: 'pages/index.vue'
    },
    {
      name: 'user'.path: '/user'.component: 'pages/user/index.vue'
    },
    {
      name: 'user-one'.path: '/user/one'.component: 'pages/user/one.vue'}}]Copy the code
  • Embedded routines by

You can create nested routes for nuxt.js applications using vue-Router children.

To create inline child routing, you need to add a Vue file and a directory with the same name as the file to store the child view components.

File path:

pages/
--| users/
-----| _id.vue // Vue files prefixed with an underscore: dynamic routing, which may be used for SSR
-----| index.vue
--| users.vue
Copy the code

Nuxt.js automatically generates the following route configuration:

router: {
  routes: [{path: '/users'.component: 'pages/users.vue'.children: [{path: ' '.component: 'pages/users/index.vue'.name: 'users'
        },
        {
          path: ':id'.component: 'pages/users/_id.vue'.name: 'users-id'}]}]}Copy the code

Six, common commands:

  • nuxt

Enable a hot loaded Web server (development mode) localhost:3000

  • nuxt build

Use Webpack to compile applications and compress JS and CSS resources (for distribution). Personally understand SSR used this

  • nuxt start

Start a Web server in production mode (based on the dist directory, nuxt build is required first).

  • nuxt generate

Compile the application and generate HTML files based on the route configuration (for static site deployment). Static use of this!!

Some places in the article for personal understanding, welcome everyone correction!