SEO Tips and Tricks for Vue Single Page Apps

Vue js

Over the last few years, single page apps (SPAs) have become increasingly more prevalent. Advances in the speed and efficiency of javascript, as well as the simplification and expansion of the language with es6 and beyond, has lead to a number of advances in how we build websites. This has greatly impacted the user experience of the web. Now when we load a webpage, we can interact with all kinds of different pieces of data and make any number of changes without having to wait for a page reload or a server to re-render all of the html for a page just to tell us whether or not that request was successful. But rendering your page dynamically with javascript has some drawbacks, as well. Have an error in your javascript? The html for your page no longer renders. An api endpoint returns a 500 error? You may have a missing or broken portion of your app. But for many, the worst consequence of building an SPA may be the lack of visibility in search results and poor SEO of a dynamically generated app.

Because of these drawbacks, SPA architecture isn’t appropriate for every app, but sometimes it does make sense. If a SPA fits your business needs, or you have an app with a lot of JS and are worried about the Googlebots of the world not being able to parse your site, all is not lost. In this post, we will go through some simple steps for increasing your app’s visibility and SEO in a sample VueJS SPA.


Some of the basics of SEO are also simply best practices for building an app, in general. Here are a few things concepts to focus on for SEO:

  • Sitemap
  • Meta-tags
  • Page Load Speed
  • Mobile Optimization

One of the many nice things about Vue is its large ecosystem of plugins. We can leverage a few plugins to help us with our SEO goals.


A good first step in improving your site’s SEO is setting up proper meta-data tags. One simple way to manage the meta-tags of your app is with a plugin called vue-meta. To set it up, it’s like any other plugin — import the package and register the plugin.

import Vue from 'vue'
import Meta from 'vue-meta'

And to set up the meta-tags site wide, simply add the ‘metaInfo’ object to your initial vue component with the appropriate information.

Setup of metaInfo:

 // assets/webpack.config.js

 export default {
   name: 'App',
   metaInfo: {
     // if no subcomponents specify a metaInfo.title, this title will be used
     title: 'Default Title',
     // all titles will be injected into this template
     titleTemplate: '%s | My Awesome Webapp'

This plugin also lets you override these defaults in other components, if you want to, for example, update the title or other data on each page to optimize SEO. All you have to do is add the metaInfo block with the relevant info and the plugin merges those objects and builds the correct meta-data.


If you are using vue-router, you can use a similar process to set up a sitemap for your app to help your users navigate your site. With the package vue-router-sitemap, you can set up a small middleware function that builds a sitemap of all your routes. Here is a simple example of the setup:

// sample vue-router setup - router.js
import VueRouter from 'vue-router'

export const router: VueRouter = new VueRouter({
 routes: [ { path: '/', name: 'home', component: Home } ],

// sitemapMiddleware.js
import VueRouterSitemap from 'vue-router-sitemap'
import path from 'path'
import { router } from 'router'

export const sitemapMiddleware = () => {
 return (req, res) => {
   res.set('Content-Type', 'application/xml')

   const staticSitemap = path.resolve('dist/static', 'sitemap.xml');
   const filterConfig = { isValid: false }

   new VueRouterSitemap(router).filterPaths(filterConfig).build('').save(staticSitemap)

   return res.sendFile(staticSitemap)

// register your endpoint
app.get('/sitemap.xml', sitemapMiddleware())

(This setup was derived from the example in this package’s github repo. More advanced setup instructions can be found there: vue-router-sitemap.)

Load Speed/ Prerender

Probably the trickiest and most intimidating metric of SEO to address is site load speed. In the case of SPA apps, this is further complicated by having to ensure that your site is rendered and ajax calls are resolved before the bot parses your site.

There are two mains strategies to address page render speed and accuracy in SPAs: server-side rendering and pre-rendering. To implement server-side rendering you will need something like Nuxt.js or a NodeJS backend to build your front-end JS on the server. Consequently, you will also give up the ability to access the browser APIs (functions like ‘window’, ‘location’, and ‘DOM’). Here at Littlelines, we tend to use a Rails or Elixir backend for most of our applications and we enjoy the flexibility of leveraging the browser APIs, so pre-rendering is a better fit for our applications.

Once again, for our example prerender setup, we will utilize a plugin from the Vue ecosystem: prerender-spa-plugin. (And once again here is a sample setup, based on the instructions in the github repo. More advanced instructions can be found there.)

const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin')

module.exports = {
  plugins: [
    new PrerenderSPAPlugin(
      // path to static root
      path.join(__dirname, 'relative/path/to/static/root-page'),

      // List of routes to prerender
      [ '/', '/team', '/contact' ],

      // (OPTIONAL) Compatible options from Vue v2.
        // These options are for async asynchronously rendered content, e.g. ajax requests

        // Wait until a specific event is fired on the document.
        captureAfterDocumentEvent: 'custom-render-event',

        // Wait until a specific element is detected with document.querySelector.
        captureAfterElementExists: '#app',

        // path of index file. By default it's index.html in static root.
        indexPath: path.resolve('/dist/path/to/index.html')

With this setup, Vue will build out the template for each route (our sample routes include home, team, and contact pages. This could be anything you want to serve from your app). The pre-rendering process involves using a headless browser to build these pages into static html files and saving these results to whatever file structure your app uses to serve its routes. This will allow you to serve these assets instantly to your users, reducing page load time and increasing SEO scores.


These are just a few ways you can increase your app’s SEO and visibility, specifically with a Vue SPA (or hybrid app, with a lot of javascript). The process of building an app that will be successful in search results and bring lots of traffic to your site may seem intimidating at first, but I hope we have proved in this post that with a little forethought and know-how, you can take a few simple steps to get you well on your way to making the coveted first page (or maybe even first few spots) of the search results queue.

Sign up to receive updates on all things Littlelines

Have a project we can help with?
Let's Talk

Get Started Today