The SEO discover for Vuejs

SEO is a indispensable part for websites. A good SEO can help website to be indexed easily by search engine. My website is built by Vuejs and hosting on firebase. In this article, I will share the SEO experience on:
1. sitemap
2. custom 404 page
3. facebook open graph
4. asset cache ability

If you are interesting in other SEO topics, you can check:

Sitemap

Sitemap can help search engines to know which pages are important and relevant on site. However, search engine can’t recognize sitemap which includes # links. Therefore, I suggest to use vue-router history mode to develop web application.

const router = new VueRouter({
mode: 'history',
routes: [...]
})

To generate the sitemap.xml, we use the sitemap webpack plugin

// webpack.config.prod.js
const SitemapPlugin = require('sitemap-webpack-plugin').default;
const prettydata = require('pretty-data');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.config.base');
const paths = [
'/'
'/docs',
'/pricing',
'/about'
]
const prettyPrint = xml => {
const result = prettydata.pd.xml(xml);
return result;
};
const config = merge(baseWebpackConfig, {
mode: 'production',
plugins: [
new SitemapPlugin('https://my.website.com/', paths, {
changeFreq: 'monthly',
skipGzip: true,
formatter: prettyPrint,
}),
],
});

After deploying the sitemap, we can go to search console to add the sitemap reference.

add sitemap in search console

If your sitemap can’t be indexed successfully, goto Crawl → Crawl Errors to see the detail messages and use Fetch as Google to check whether the page is rendered successfully or not.

Custom 404 page

If user try to visit the none-exist url of website, we should give user a custom 404 page. It can reduce user frustration and help user to find out which part they can visit on website. ( reference: Great 404 error pages)

Example:

Airbnb — custom 404 page

Implementation:

Using vue-router history mode only handle 1 case for 404 not found page. (e.g. https://mysite.com/page/not/found). When we set the vue-router to history mode, we should catch-all fallback route to server. Here is the example for firebase hosting configuration:

// firebase.json
{
"hosting": {
"public": "dist",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}

Bue, how to catch-all fallback in development ?

we use the devSer.historyApiFallback to configure webpack file.

// webpack.config.dev.js
const config = merge(baseWebpackConfig, {
mode: 'development',
devServer: {
contentBase: path.join(__dirname, 'static'),
historyApiFallback: {
index: '/your-public-path/'
}
}
});

Now, we can implement a catch-all route to show a 404 page.

const router = new VueRouter({
mode: 'history',
routes: [
{ path: '*', component: NotFoundComponent }
]
})

Facebook Open Graph

Facebook Open Graph can enrich website content when we sharing the link on social medias. ( use Facebook debug tool to verify after adding the meta tags.)

<meta property="og:site_name" content="My Website"/>
<meta property="og:type" content="article"/>
<meta property="og:title" content="my website title"/>
<meta property="og:url" content="https://my.website.com/">
<meta property="og:description" content="my website description"/>
<meta property="og:image" content="https://my.storage/image.png"/>
Evernote — preview on social network

Ideally, we want to add different meta tags to each page. However, Vuejs is Single Page Application (SPA), which means all links are handled by single route. The crawler don’t run our Javascript to find the meta data. Therefore, we need to simulate the static HTML files for each route.

There are two common approaches to solve SPA problems

  1. Prerendering
  2. Server-Side Rendering

Prerendering is a methods to generate static HTML files to each route at build time. It’s a simpler solution than Server-Side Rendering. Following is the example webpack configurations which use prerender-spa-plugin.

// webpack.config.prod.js
const config = merge(baseWebpackConfig, {
mode: 'production',
....
plugins: [
new PrerenderSPAPlugin({
staticDir: path.resolve(__dirname, 'dist/'),
routes: ['/', '/about', '/docs'],
postProcess(context) {
context.path = context.originalPath;
const titles = {
'/': 'My Website',
'/about': 'DeepQ AI Platform - About',
'/docs': 'DeepQ AI Platform - Docs',
};
const desc = {
'/': 'Home Page Descriptions',
'/about': 'About Page Descriptions',
'/docs': 'Docs Page Descriptions',
};
          context.html = context.html.replace(
/<title>[^<]*<\/title>/i,
'<title>' + titles[context.route] + '</title><meta name="description" content="'+desc[context.route]+'">'
);
return context;
},
}),
],
});

Although prerender-spa-plugin is easy to use, it’s not perfect. It can’t support multi-language. It’s hard to maintain when website has a large amount of routes.

Browser Caching

Consider the web performance and user experience, we don’t want user download assets every time. Therefore, we need to set cache to static files.

// firebase.json
"headers": [ {
"source" : "**/*.@(jpg|jpeg|gif|png)",
"headers" : [ {
"key" : "Cache-Control",
"value" : "max-age=7200"
} ]
}, {
// Sets the cache header for 404 pages to cache for 5 minutes
"source" : "404.html",
"headers" : [ {
"key" : "Cache-Control",
"value" : "max-age=300"
} ]
} ]

Summary

In conclusion, for a vue developer to do SEO I will suggest:

  1. vue-router use history mode
  • let sitemap.xml can be indexed by google search engine
  • handle the single case for 404 not found page 
    ( in hash mode, you need to handle https://mysite.com/page/not/found/# and https://mysite.com/#/page/not/found)

2. If your website is a static or small website, I recommend to use prerender-spa-plugin to add meta-tags to each route.

Like what you read? Give Jacky Tung a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.