Vue.js Tutorial: Building a pre-rendered SEO friendly application example

Keywords: Vue npm Webpack React

What is Vue.js exactly?


Vue.js is a lightweight, incremental JavaScript framework that helps you build your user interface

Don't be fooled by the definition of JS Framework.Vue is distinct from the current popular React.js & Angular.js.For beginners, it is not an open source by-product of commercial technology giants such as Google & Facebook.

Evan You (Yuyuxi) first released it in 2014 with the goal of creating a modern JS library for incremental development.One of the most powerful features of Vue is to create reusable components that you can reuse in other projects without having to write them again.All developers can try Vues in their projects without worrying about harming existing code libraries or adding additional burdens.

Regardless of patterns and terminology, I think Vue makes the following remarks:

1. At first you don't know the architecture state of the entire application
2. Application data is bound to change at runtime

It is around these propositions that Vue shapes itself: it is progressive, component-based and responsive.Granularization of components allows you to easily separate application logic while maintaining their reusability.More importantly, it binds your data natively to the view to "magically" update when needed (via watcher).Although many responsive front-end frameworks have the same functionality, I find that Vue implements it more elegantly and tends to perform better for most of my use cases.

Vue also has a smoother learning curve, so for React, we need to know something about JSX templates and so on.It can even be said that Vue is React minus more complex parts.

The official Vue documentation provides a more in-depth comparison with other JS frameworks (React, Angular, Ember, Knockout, Polymer, Riot). View official documents

Last but not least: thanks to the high performance & powerful development tools, Vue provides us with the best coding experience.It can So popular That's not surprising!

vuejs popularity

From Open Source Projects LaravelPageKit To enterprises such as GitlabCodeship (Not to mention the giants Alibaba and Baidu), many organizations are using Vue.

OK, now is the time to see how we'll use it.

Example of Vue.js: A fast, search engine friendly e-commerce application

In this section, I'll show you how to build a small e-commerce application using Vue 2.0 & Snipcart.We will also see how to ensure that product pages are "grabbed" correctly by search engines.

Get ready

If you want to learn more about Vue 2.0, check out the This series.

1. Environment Configuration

First, we'll use vue-cli to build basic Vue applications.In your favorite terminal, enter:

npm install -g vue-cli
vue init webpack-simple vue-snipcart

This will create a new vue-snipcart folder with basic configuration using vue-loader, which will enable us to write single file components (template/js/css in the same.Vue file).

We want this example to be as realistic as possible, so we'll add two modules to this application that are widely used in large projects: vuex and vue-router.

  • vuex is a state manager for Flux-like architectures - lightweight and very powerful.It's influenced by Redux, you can be here Learn more.
  • vue-router allows you to define routes to dynamically process components of your application.

To install these, first enter the vue-snipcart project folder, and then run the following command:

npm install --save vue-router
npm intsall --save vuex

The next thing to install is prerender-spa-plugin, which will allow us to prerender the path that the Spider will crawl:

npm install --save prerender-spa-plugin

Nearly finished, the last four packages:

  • pug - Template Engine, I prefer it to HTML.
  • vuex-router-sync-to - Easily keep vue-router and vuex storage synchronized.
  • copy-webpack-plugin-to - Easily contains our static files in the dist folder.
  • babel-polyfill - Run Vue in PhantomJS (using our pre-rendering plug-in).

Run these:

npm install --save pug
npm install --save vuex-router-sync
npm install --save copy-webpack-plugin
npm install --save babel-polyfill

2. Architecture

Check if the installation is correct after the installation is complete.Then we can process our store data.

Start with vuex's store and we'll use it to store/access our product information.

In this demonstration, we will use static data and it will still work if we want to replace it.

Note: For Snipcart, we use Basic JS snippets Inject the shopping cart and use simple HTML Properties Define the product.

2.1 Building a store

Create a store folder in src that contains the following three files:

  • state.js - Define our static product data
  • getters.js - Defines get functions to retrieve products by ID
  • index.js - Combine the first two files
export const state = {
    products: [
            id: 1,
            name: 'The Square Pair',
            price: 100.00,
            description: 'Bold & solid.',
            image: ''
            id: 2,
            name: 'The Hip Pair',
            price: 110.00,
            description: 'Stylish & fancy.',
            image: ''
            id: 3,
            name: 'The Science Pair',
            price: 30,
            description: 'Discreet & lightweight.',
            image: ''

    export const getters = {
        getProductById: (state, getters) => (id) => {
            return state.products.find(product => == id)

import Vue from 'vue'
import Vuex from 'vuex'
import { state } from './state.js'
import { getters } from './getters.js'


export default new Vuex.Store({

2.2 Building Routers

We will keep the store as simple as possible: showing the first page of the product list and the details page for each product.We need to register two routes in the router to process these routes:

import VueRouter from 'vue-router'
import Vue from 'vue'
import ProductDetails from './../components/productdetails.vue'
import Home from './../components/home.vue'


export default new VueRouter({
  mode: 'history',
  routes: [
    { path: '/products/:id', component: ProductDetails },
    { path: '/', component: Home },

We haven't created these components yet. Don't worry, we'll be right there;)

Notice that we used mode:'history'in the VueRouter declaration.This is important, otherwise our prerender plug-in will not work.The difference is that the router will use history API instead of hashbang to navigate.

2.3 Combine everything together

Now that we have data (stores) and routers, we need to register them with the application.Update your src/main.js file:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { sync } from 'vuex-router-sync'
import store from './store'

sync(store, router)

new Vue({
  render: h => h(App)

It's easy!As mentioned earlier, the sync method in vuex-router-sync injects state from our store into the current route.We'll use it later.

3. Write Vue components

It feels great to have data, but it would be better to show it.The three components we're going to use:

  • Home - Show product list
  • Product - Individual product information, which will be used in Home components
  • ProductDetails - Product Details Page

They will be included in the src/components folder.


<template lang="pug">
        div(v-for="product in products", class="product")

import Product from './../components/Product.vue'

export default {
  name: 'home',
  components: { Product },
  computed: {
      return this.$store.state.products

Above, we use the states in the store to get our products and iterate over them to render each product.

<template lang="pug">
      img(v-bind:src="product.image" v-bind:alt="" class="thumbnail" height="200")
      p {{ }}
        | Buy it for {{ product.price }}$

export default {
  name: 'Product',
  props: ['product'],
  computed: {
      return `/products/${}`

From the router, we link to another page (ProductDetails) to see our last component:

<template lang="pug">
    img(v-bind:src="product.image" v-bind:alt="" class="thumbnail" height="200")
    div(class="product-description" v-bind:href="url")
      p {{ }}
      p {{ product. description}}

          | Buy it for {{ product.price }}$


export default {
  name: 'ProductDetails',
  computed: {
      return this.$
      return this.$store.getters.getProductById(

The logic in this section is slightly more complex: we get the current ID from the route, then get the relevant product information from the getter we created earlier.

4. Create App

Let's start using the components we just created.

Open the App.vue file, which is the default content generated by the scaffold (vue init webpack-simple).Let's modify it:

<template lang="pug">


import TopContext from './components/TopContext.vue'

export default {
  name: 'app',
  components: { TopContext }

The TopContext component is not important, it is just a header.The key part is router-view: it will dynamically load components through VueRouter, and the components previously associated with it will be replaced.

Finally, let's update index.html.For our use case, we create a new directory static in src, move the index.html file to static, and update it to the following:

<!DOCTYPE html><html lang="en">
    <meta charset="utf-8">

    <div id="app">    
    <script src="/build.js"></script>
    <script src=""></script>
    <script src="" data-api-key="YjdiNWIyOTUtZTIyMy00MWMwLTkwNDUtMzI1M2M2NTgxYjE0" id="snipcart"></script>
    <link href="" rel="stylesheet" type="text/css" />

As you can see, we added the necessary scripts for Snipcart to index.html.Code that finely divides them into components looks cleaner, but since all of our View s need them, we do so.

5. Use Prerender plug-in to handle Vue.js SEO

vuejs seo prerendering

All the content in our application is rendered dynamically using JS, which is very detrimental to Search Engine Optimization (SEO): Asynchronous content in web pages cannot be effectively recognized and captured by "search engine bots". In this case, our e-commerce website misses all useful "web crawlers", which is not a wise choice!

Let's use prerendering technology to bring more SEO opportunities to our Vue.js applications.

prerendering is easier to use than Vue's SSR (server-side rendering).To be frank, the former Some have been overcorrected Unless you have a large number of routes to process.In addition, the two technologies achieve similar results at the level of SEO.

Pre-rendering will enable us to keep our front-end as a fast, lightweight static website for "spiders" to crawl.

Let's see how to use it: Go to the WebPack configuration file and add the following configuration to the plugin configuration item:

plugins: [
  new CopyWebpackPlugin([{
    from: 'src/static'
  new PrerenderSpaPlugin(
    path.join(__dirname, 'dist'),
    [ '/', '/products/1', '/products/2', '/products/3']

Okay, how does it work?

CopyWebpackPlugin copies the files in the static folder to the dist folder (contains only views of applications that reference Vue App).PrerenderSpaPlugin then uses PhantomJS to load the contents of the page and uses the results as our static resources.

Look!We have now provided pre-rendered, SEO-friendly product pages for our Vue applications.

We use the following commands to test:

npm run build

This generates a dist folder that contains everything needed for the production environment.

Other important SEO factors

  1. Consider adding appropriate meta tags and Sitemaps to your page.You can learn about meta tags in the postProcessHtml function (configuration item for the prerender-spa-plugin plugin) More information.
  2. Proper Content It plays an important role in modern SEO.It is recommended that you ensure that the content in your application is easy to create, edit, and optimize.To authorize content editors, consider putting headless CMS in a mix and building a real JAMstack.
  3. HTTPS connections are now officially Google's ranking factor.We are in Netlify Hosted on, Netlify provides us with a free SSL certificate.
  4. Mobile-first indexing and mobile-friendliness It is also an important factor in ranking.Make sure your mobile experience is as fast and complete as the desktop version!

GitHub Library and Online Demo

To learn more, please join 627336556 Technology Development Exchange Group, you will get unexpected gains ~~!!!(

Posted by edspace on Thu, 06 Jun 2019 10:11:57 -0700