vue-cli-plugin-sitemap
vue-cli-plugin-sitemap generates sitemaps for your Vue web apps. You can use
it on its own or integrate it in the definition of the routes used in Vue
Router. Features:
- 🛣️ generate sitemaps from an array of routes
- 🔀 support dynamic routes with single or multiple parameters
- 🍱 support nested routes
- 🚧 automatically escape the URLs and enforce a (non-)trailing slash policy
- ✂️ automatically split the large sitemaps (more than 50,000 URLs) and generate
the associated sitemap index
- ✨ optionally prettify the output
Table of contents
Installation
vue add sitemap
The plugin will add a script called sitemap
to your package.json
. No other
files will be modified.
Setup
Usage with vue-router
The recommended way to provide data to the plugin is to pass it the array of
routes used by Vue Router. To do this, you'll need to separate the declaration
of the routes and the instantiation of the Vue Router into two different
modules.
Below is a simplified example of this setup, using esm
to load ES6 modules into vue.config.js
(this is needed until #4477
is implemented). Note that this comes with a few restrictions in src/routes.js
:
- you can import other JS modules, but no
.vue
files because esm
won't know
how to load them (you'll have to rely on dynamic imports using Node's
require()
for the component
property) - you can't use the
@
placeholder in the inclusion paths, as this is a bit of
sugar syntax defined by vue-loader
to shorten paths when loading files with
webpack
require = require('esm')(module);
const { routes } = require('./src/routes.js');
module.exports = {
pluginOptions: {
sitemap: {
baseURL: 'https://example.com',
routes,
}
}
}
export const routes = [
{
path: '/',
name: 'home',
component: () => import( './views/Home.vue')
},
{
path: '/about',
name: 'about',
component: () => import( './views/About.vue')
},
]
import Vue from 'vue'
import Router from 'vue-router'
import App from './App.vue'
import { routes } from './routes.js'
Vue.use(Router);
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
new Vue({ router, render: h => h(App) }).$mount('#app');
Usage as a standalone plugin
You can also directly provide some handwritten URLs to the plugin:
module.exports = {
pluginOptions: {
sitemap: {
urls: [
'https://example.com/',
'https://example.com/about',
]
}
}
}
If both routes and URLs are provided, they will be merged together in a single
sitemap. In the case of duplicated locations, handwritten URLs will prevail over
their matching routes.
CLI
To examine the output without triggering the whole build process, run the
following command to generate a sitemap in the current working directory:
npm run sitemap
CLI options
When running the plugin on the command line, it will follow the options set in
vue.config.js
. If needed, you can overwrite those with some CLI options:
-p
, --pretty
: produce a human-readable output-o <dir>
, --output-dir <dir>
: specify a directory in which the sitemap
will be written
Note: when calling the CLI through npm scripts, don't forget to add --
before
specifying the options to ensure that npm won't capture them, e.g. npm run sitemap -- --pretty -o dist/
.
Options
Global options
All the global options are optional and can be omitted, except for baseURL
that must be provided for route-based sitemaps.
sitemap: {
productionOnly: true,
outputDir: '/temp/sitemap',
trailingSlash: false,
hashMode: false,
pretty: true,
baseURL: 'https://example.com',
defaults: {
lastmod: '2020-01-01',
changefreq: 'weekly',
priority: 1.0,
},
}
URL meta tags
In the sitemap format, each URL can be associated with some optional meta tags
to help the crawlers update the pages and prioritize the critical URLs:
Meta tag | Accepted values for the equivalent property | Default value if absent |
---|
lastmod | a date string in the W3C format, a JavaScript timestamp string, a numeric timestamp or a Date object | Ø |
changefreq | "always" , "hourly" , "daily" , "weekly" , "monthly" , "yearly" , "never" | Ø |
priority | a multiple of 0.1 between 0.0 and 1.0 | 0.5 |
For more information on those meta tags, you can consult the official specification.
Example with a route object:
{
path: '/about'
component: () => import( './About')
meta: {
sitemap: {
lastmod: 'December 22, 2019',
priority: 0.8,
changefreq: 'daily',
}
}
}
Example with a handwritten URL:
sitemap: {
urls: [
{
loc: 'https://example.com/about',
lastmod: 'December 22, 2019',
priority: 0.8,
changefreq: 'daily',
},
]
}
Dynamic routes
If you use dynamic routes (e.g. /user/:id
), you must provide some slugs to
generate the corresponding URLs (or set the ignoreRoute
option to true):
module.exports = [
{
path: '/articles/:title',
meta: {
sitemap: {
slugs: [
'my-amazing-article',
'a-life-changing-method-for-folding-socks',
{
title: 'a-very-important-article',
priority: 1.0,
}
],
}
}
},
{
path: '/blog/:category/:id(\\d+)/:post?',
meta: {
sitemap: {
slugs: [
{
id: 1,
title: 'hello-world',
category: 'infos',
},
{
id: 2,
title: 'how-to-fold-socks-faster',
category: 'lifehacks',
priority: 0.9,
lastmod: 'February 02, 2020 09:24',
},
{
id: 'invalid-slug',
title: 'another-post',
category: 'misc',
}
]
}
}
},
{
path: '/user/:id',
meta: {
sitemap: {
slugs: async () => await getActiveUsers(),
}
}
},
]
Nested routes
Nested routes are supported:
module.exports = [
{
path: '/user/:id',
meta: {
sitemap: {
changefreq: 'monthly',
priority: 0.7,
slugs: getUserList(),
}
},
children: [
{
path: 'profile',
meta: {
sitemap: {
changefreq: 'weekly',
}
}
},
]
},
]
This example will produce the following sitemap:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/user/1/profile</loc>
<priority>0.7</priority>
<changefreq>weekly</changefreq>
</url>
<url>
<loc>https://example.com/user/2/profile</loc>
<priority>0.7</priority>
<changefreq>weekly</changefreq>
</url>
</urlset>
Other route-specific options
module.exports = [
{
path: '/admin/secure-page',
meta: { sitemap: { ignoreRoute: true } }
},
{
path: '*',
name: '404',
},
{
path: '/glob/*',
meta: { sitemap: { loc: '/glob/lorem/ipsum' } }
},
]
Changelog
You can consult the full changelog here.
License
This software is distributed under the ISC license.