VitePress CMS Integration
VitePress is a static site generator, but it can be fully integrated with Headless CMS, enabling non-technical personnel to easily manage website content. By connecting VitePress with a CMS, you can separate content management from site display.
Basic Concept
The core idea of integration is: at build time, fetch content from the CMS API, then use this data to generate static Markdown files or directly render content in Vue components.
We will use data loading (*.data.js) functionality to implement this, which is the ideal way provided by VitePress for fetching external data at build time.
Example: Integrating Strapi
Assume we're using Strapi as our Headless CMS, and we have a collection type named articles.
1. Create Data Loader File
Create a data loader file in your project, such as docs/articles.data.js. This script will run at build time and fetch the article list from the Strapi API.
// docs/articles.data.js
import fetch from 'node-fetch' // Node.js environment needs to import fetch
export default {
async load() {
try {
const res = await fetch('https://your-strapi-instance.com/api/articles')
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`)
}
const data = await res.json()
// Strapi data is usually under the `data` attribute
return data.data
} catch (error) {
console.error('Failed to fetch articles:', error)
return [] // Return empty array on error
}
}
}Note: You may need to handle authentication, for example, by adding an API token to the request headers.
2. Create Page to Display Content
Now, create a Markdown file docs/articles.md to display the article list we fetched from the CMS.
<!-- docs/articles.md -->
<script setup>
import { useData } from 'vitepress'
// The value of the `data` variable is the result returned from articles.data.js
const { data: articles } = useData()
</script>
# Latest Articles
<div class="article-list">
<div v-for="article in articles" :key="article.id" class="article-item">
<h2>{{ article.attributes.title }}</h2>
<p>{{ article.attributes.summary }}</p>
<!-- You can create a dynamic route page to display article details -->
<a :href="`/articles/${article.attributes.slug}`">Read More</a>
</div>
</div>
<style scoped>
.article-list .article-item {
margin-bottom: 2rem;
border-bottom: 1px solid var(--vp-c-divider);
padding-bottom: 1rem;
}
</style>3. Generate Dynamic Route Pages (Optional)
For article detail pages, you can use VitePress's dynamic routing functionality. You need to modify the configuration file to tell VitePress to generate corresponding pages based on data fetched from the CMS.
// .vitepress/config.js
import fetch from 'node-fetch'
export default {
// ...
async buildEnd(siteConfig) {
// Here you can generate dynamic pages, but this usually requires more complex setup
// A more common approach is to use MPA mode or custom build scripts
}
}A simpler approach is to run a separate Node.js script before building:
- Fetch all articles from the CMS.
- Dynamically create a Markdown file for each article (such as
docs/articles/my-first-article.md), where the file content can be a simple template that references a Vue component to display article details. - Run
vitepress build.
Advantages
- Content Decoupling: Content managers can work in a friendly CMS interface while developers focus on code.
- Excellent Performance: The final website remains completely static with fast loading speed and SEO friendliness.
- Security: Since there's no direct database connection, the attack surface is reduced.
Through this approach, you can combine VitePress's development experience and performance advantages with the content management flexibility of Headless CMS.