sitemap.hostname config optionVitePress is a static site generator built on Vite and Vue 3, designed for documentation sites and content-heavy blogs. The initial visit serves pre-rendered HTML for fast loading and optimal SEO, while subsequent navigation behaves like an SPA.
VitePress beats Nuxt Content when:
VitePress has 395,965 weekly npm downloads vs Nuxt Content's 74,690. Choose Nuxt Content when you need SSR, complex routing with non-markdown pages, or deeper integration with Nuxt modules.
VitePress pre-renders pages at build time, generating static HTML files. This approach delivers excellent SEO while maintaining SPA benefits for user experience.
On PageSpeed Insights, VitePress sites achieve near-perfect performance scores even on low-end mobile devices—Google's Core Web Vitals directly impact rankings.
VitePress includes native sitemap support. Enable it in .vitepress/config.ts:
export default {
sitemap: {
hostname: 'https://mysite.com'
}
}
This generates sitemap.xml in .vitepress/dist during build. For <lastmod> tags, enable the lastUpdated option:
export default {
sitemap: {
hostname: 'https://mysite.com'
},
lastUpdated: true
}
VitePress uses the sitemap module under the hood. Pass any SitemapStream options directly to the sitemap config.
Use transformItems to modify sitemap entries before writing:
export default {
sitemap: {
hostname: 'https://mysite.com',
transformItems: (items) => {
// Filter out draft pages
return items.filter(item => !item.url.includes('/drafts/'))
}
}
}
For advanced use cases, use VitePress build hooks like buildEnd to generate custom sitemaps:
import { writeFileSync } from 'node:fs'
import { SitemapStream, streamToPromise } from 'sitemap'
export default {
async buildEnd(siteConfig) {
const sitemap = new SitemapStream({ hostname: 'https://mysite.com' })
const pages = await generatePageList(siteConfig)
pages.forEach(page => sitemap.write(page))
sitemap.end()
const data = await streamToPromise(sitemap)
writeFileSync('.vitepress/dist/sitemap.xml', data.toString())
}
}
Add meta tags globally using the head config:
export default {
head: [
['meta', { name: 'description', content: 'My documentation site' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:image', content: 'https://mysite.com/og.png' }],
['link', { rel: 'icon', href: '/favicon.ico' }]
]
}
User-added tags render before the closing </head> tag, after VitePress's built-in tags.
Override meta tags per page using frontmatter:
---
head:
-
- meta
- name: description
content: Custom description for this page
-
- meta
- property: og:title
content: Custom OG Title
-
- meta
- name: keywords
content: vitepress, seo, vue
---
Frontmatter meta tags append after site-level tags. Note that setting OG tags globally and overriding per-page can cause duplicate tags in HTML output.
For dynamic meta tags, use transform hooks:
export default {
transformPageData(pageData) {
pageData.frontmatter.head ??= []
pageData.frontmatter.head.push([
'meta',
{
property: 'og:title',
content: pageData.frontmatter.layout === 'home'
? 'Homepage - My Site'
: pageData.title
}
])
}
}
transformPageData runs during both dev and build. For build-only transforms, use transformHead, but note it doesn't run during development.
VitePress includes fuzzy full-text search using minisearch. Enable local search in .vitepress/config.ts:
export default {
themeConfig: {
search: {
provider: 'local'
}
}
}
No external service required—search runs in-browser using an indexed bundle.
For larger sites, integrate Algolia DocSearch:
export default {
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_API_KEY',
indexName: 'YOUR_INDEX_NAME'
}
}
}
}
Algolia crawls your site and provides advanced search with typo tolerance and result ranking.
VitePress supports clean URLs without .html extensions. Enable them in config:
export default {
cleanUrls: true
}
Clean URLs avoid duplicate content issues where /page and /page.html are treated as separate URLs. This matters for sitemaps and canonical tags—search engines mark mismatched URLs as duplicate content.
| Feature | VitePress | Nuxt Content |
|---|---|---|
| Build Speed | Blazing fast with Vite | Slower with larger sites |
| Use Case | Documentation, blogs, static content | Full web apps with markdown |
| SSR | Static-only | Full SSR + SSG |
| Search | Built-in local search | Requires integration |
| Learning Curve | Simpler, minimalistic | Steeper, feature-rich |
| Page Directory | Markdown only | Mixes markdown + Vue pages (with friction) |
| Ecosystem | Growing, documentation-focused | Larger, mature module system |
| Authentication | Doesn't fit SSG model | Supported with SSR |
VitePress excels for performance-critical static sites where all content is known at build time. Nuxt Content handles complex routing, dynamic content, and SSR requirements better.
Nuxt offers deeper SEO integration through @nuxtjs/seo, which handles sitemaps, robots.txt, structured data, and OG images with zero configuration.