DEV Community

Paul Laros πŸ‡³πŸ‡±
Paul Laros πŸ‡³πŸ‡±

Posted on • Originally published at laros.io on

Generating a dynamic sitemap with VitePress

By including a sitemap on your website, you can ensure that all pages are indexed by search engines, which can improve your site's visibility in search results and make it easier for users to navigate.

Build Hooks

VitePress build hooks enable you to enhance the functionality of your website, such as adding sitemaps, PWA support, and search indexing. In the examples below we're using the transformHtml hook to collect all the links, and buildEnd hook to generate the sitemap XML file.

Dependencies

Before getting started, make sure to install the sitemap npm module. The module allows developers to easily create sitemaps in XML format.

npm install sitemap -D

Enter fullscreen mode Exit fullscreen mode

Configuring VitePress

Place the following snippet in your VitePress config file, adjust the URL, and run vitepress build to compile a sitemap.

.vitepress/config.ts

import { createContentLoader, defineConfig } from 'vitepress'
import { SitemapStream } from 'sitemap'
import { createWriteStream } from 'node:fs'
import { resolve } from 'node:path'

export default defineConfig({
  lastUpdated: true,
  buildEnd: async ({ outDir }) => {
    const sitemap = new SitemapStream({ hostname: 'https://laros.io/' })
    const pages = await createContentLoader('*.md').load()
    const writeStream = createWriteStream(resolve(outDir, 'sitemap.xml'))

    sitemap.pipe(writeStream)
    pages.forEach((page) => sitemap.write(
      page.url
        // Strip `index.html` from URL
        .replace(/index.html$/g, '')
        // Optional: if Markdown files are located in a subfolder
        .replace(/^\/docs/, '')
      ))
    sitemap.end()

    await new Promise((r) => writeStream.on('finish', r))
  }
})

Enter fullscreen mode Exit fullscreen mode

Clean URLs

If you have clean URLs enabled, use the following regex instead. Everything else can remain the same.

// If `cleanUrls is enabled`
.replace(/index$/g, '')
// If `cleanUrls` is disabled
.replace(/index.html$/g, '')

Enter fullscreen mode Exit fullscreen mode

Resources

Top comments (3)

Collapse
 
mandrasch profile image
Matthias Andrasch

Hey, thanks for the tutorial, awesome!

This blog post here is missing the import { createContentLoader} from 'vitepress', got an error first.

But saw that you updated laros.io/generating-a-dynamic-site...

Cheers!

Collapse
 
mandrasch profile image
Matthias Andrasch • Edited

And my sitemap is missing some sub sites for my-ddev-lab.mandrasch.eu/ which are in subfolders, but I'll debug this myself of course. πŸ€“

Update: Fixed it with const pages = await createContentLoader(["**/*.md"]).load();

Collapse
 
paullaros profile image
Paul Laros πŸ‡³πŸ‡±

Updated, thanks!