These integration guides are not official documentation and the Strapi Support Team will not provide assistance with them.
What Is VitePress?
VitePress is a static site generator built on Vite optimized for speed and performance. It offers a seamless developer experience with features like hot module replacement (HMR) and automatic page preloading. VitePress is well-suited for documentation sites, with simple configuration and easy Vue.js integration.
Thanks to Vite's fast build system, VitePress provides quick build times and efficient rendering. Its minimalist design ensures easy customization, making it ideal for developers who need fast, SEO-friendly documentation and static websites.
Why Integrate VitePress with Strapi
Integrating VitePress with Strapi combines the strengths of both platforms. This combination offers developers a powerful solution for fast, dynamic, content-driven websites.
Key Benefits
- Fast, Content-Rich Websites: Strapi’s content management and VitePress’s static site generation deliver high-performance, content-rich sites without compromising speed.
- Separation of Concerns: Content editors manage content in Strapi, while developers focus on frontend development with VitePress. This separation streamlines workflows, allowing both teams to work independently.
Strapi’s Headless CMS Features
- Customizable Content: Create custom content types, manage roles, and control access.
- API-First Approach: Exposes content through REST or GraphQL endpoints for easy integration with VitePress.
Developer Experience
- Vue-Based Development: VitePress offers a Vue-powered environment with hot module replacement and TypeScript support.
- Flexible Content Retrieval: VitePress fetches content from Strapi’s REST or GraphQL API during build time. For real-time updates, implement client-side fetching.
- Extensibility: Strapi’s robust plugin system extends functionality, while VitePress supports Vue components in Markdown for enhanced UI.
Performance & SEO
- Fast Load Times: VitePress’s static output ensures quick load times and strong SEO.
- Scalable Integration: As your project grows, this integration scales easily, allowing you to add new features without performance issues.
This modular approach provides a solid foundation for modern, content-driven websites, from blogs to comprehensive documentation sites.
Keep in touch with the latest Strapi and Vitepress updates
How to Integrate and Deploy VitePress with Strapi
Integrating VitePress with Strapi creates a powerful stack, combining dynamic content management with fast static site generation. Here’s how to set up and deploy these technologies for production.
1. Set Up the Development Environment
Create separate directories for the VitePress frontend and Strapi backend:
1project-root/
2├── frontend/ # VitePress application
3│ ├── docs/
4│ ├── .vitepress/
5│ └── package.json
6├── backend/ # Strapi application
7│ ├── src/
8│ ├── config/
9│ └── package.json
10└── README.md
Initialize VitePress in the frontend directory:
1npm init vitepress
Set up Strapi in the backend directory:
1npx create-strapi-app@latest .
2. Configure API Endpoints
Create necessary content types and API endpoints through the Strapi admin panel.
Then set up an API client in your VitePress project:
1// .vitepress/api/strapi.js
2import axios from 'axios'
3
4const apiURL = import.meta.env.VITE_API_URL || 'http://localhost:1337/api'
5
6const api = axios.create({
7 baseURL: apiURL,
8 headers: {
9 'Content-Type': 'application/json'
10 }
11})
12
13export default api
Use Data Fetching Strategies
Create modular fetch functions for different content types:
1// .vitepress/api/articles.js
2import api from './strapi'
3
4export const getArticles = async (params = {}) => {
5 try {
6 const response = await api.get('/articles', { params })
7 return response.data
8 } catch (error) {
9 console.error('Error fetching articles:', error)
10 return { data: [] }
11 }
12}
4. Implement Dynamic Route Generation
Generate routes based on your Strapi content:
1// .vitepress/config.js
2import { defineConfig } from 'vitepress'
3import { getArticles } from './api/articles'
5. Adopt Deployment Best Practices
Use environment variables for API URLs, but do not expose sensitive tokens in client-accessible variables like VITE_API_TOKEN. Store and use tokens securely on the server side.
Implement proper caching strategies:
1// .vitepress/api/cache.js
2const cache = new Map()
3
4export const getCachedData = async (key, fetchFn, ttl = 60000) => {
5 const cachedItem = cache.get(key)
6
7 if (cachedItem && Date.now() - cachedItem.timestamp < ttl) {
8 return cachedItem.data
9 }
10
11 const data = await fetchFn()
12
13 cache.set(key, {
14 data,
15 timestamp: Date.now()
16 })
17
18 return data
19}
Configure CORS in Strapi for production by exporting an array with the 'strapi::cors' middleware in 'config/middlewares.js', like this:
1module.exports = [
2 // ...other middlewares
3 {
4 name: 'strapi::cors',
5 config: {
6 origin: ['https://your-vitepress-site.com'],
7 headers: ['Content-Type', 'Authorization', 'Origin'],
8 methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
9 },
10 },
11];
Set up a webhook in Strapi to trigger VitePress rebuilds:
1// Strapi webhook configuration
2{
3 "name": "Trigger VitePress rebuild",
4 "url": "https://api.netlify.com/build_hooks/your-build-hook-id",
5 "headers": {
6 "Content-Type": "application/json"
7 },
8 "events": [
9 "entry.create",
10 "entry.update",
11 "entry.delete"
12 ]
13}
The configuration of webhooks in Strapi lets you automate your static site generation process. This approach is similar to static site generation with Strapi, where changes in content trigger site rebuilds.
Optimize Strapi queries for performance:
1const getOptimizedArticles = async () => {
2 const response = await api.get('/articles', {
3 params: {
4 fields: ['title', 'slug', 'publishedAt'],
5 populate: {
6 featuredImage: {
7 fields: ['url', 'alternativeText']
8 }
9 },
10 pagination: {
11 page: 1,
12 pageSize: 10
13 },
14 sort: ['publishedAt:desc']
15 }
16 })
17 return response.data
18}
These steps will help you create a robust integration between VitePress and Strapi that is ready for production. This setup gives you dynamic content management with the speed benefits of static sites.
We recommend updating both platforms, implementing proper error handling, and monitoring your deployment. This will give you a flexible, scalable solution for content-driven websites that can grow with your needs.
Keep in touch with the latest Strapi and Vitepress updates
Project Example (+ GitHub Project Repo)
Let's walk through a real-world example of how integrating VitePress with Strapi works.
Project Architecture
The architecture follows a clean separation of concerns:
- Strapi Backend: Handles content creation and storage.
- VitePress Frontend: Generates static pages based on Strapi content.
- API Layer: Connects Strapi with VitePress.
This setup allows content editors to work within Strapi while developers focus on frontend development with VitePress.
Key Integration Points
There are three core elements that drive the integration:
- Content Fetching: VitePress fetches data from Strapi’s API during the build process.
- Dynamic Route Generation: VitePress generates routes based on Strapi content.
- Markdown Rendering: Strapi’s content is converted to Markdown for VitePress to process.
Code Walkthrough
Let's examine key code snippets from a sample GitHub project showing Strapi integration (note: this example uses React, but the concepts apply to VitePress):
For API configuration:
1// api.js
2import axios from 'axios';
3
4const api = axios.create({
5 baseURL: 'http://localhost:1337/api',
6});
7
8export const fetchArticles = async () => {
9 try {
10 const response = await api.get('/articles');
11 return response.data;
12 } catch (error) {
13 console.error('Error fetching articles:', error);
14 return [];
15 }
16};
This creates a reusable API client for fetching Strapi data. You can use this during the build process in VitePress.
For dynamic route generation, VitePress relies on its file-based routing system and does not support an asynchronous 'buildEnd' hook for injecting routes. Instead, generate route files or use available plugins and build-time scripts to create content dynamically.
For content rendering, create a Vue component:
1<!-- ArticleContent.vue -->
2<script setup>
3import { ref, onMounted } from 'vue'
4import { fetchArticles } from '../api'
5
6const articles = ref([])
7
8onMounted(async () => {
9 const response = await fetchArticles()
10 articles.value = response.data
11})
12</script>
13
14<template>
15 <div>
16 <article v-for="article in articles" :key="article.id">
17 <h2>{{ article.attributes.title }}</h2>
18 <div v-html="article.attributes.content"></div>
19 </article>
20 </div>
21</template>
You can use this component within VitePress Markdown files:
1# Our Blog
2
3Here are our latest articles:
4
5<ArticleContent />
This setup combines the best of both worlds—content management through Strapi and static site generation through VitePress. Content editors manage content in Strapi's interface, while developers benefit from VitePress for high-performance, static site generation.
Strapi Open Office Hours
If you have any questions about Strapi 5 or just would like to stop by and say hi, you can join us at Strapi's Discord Open Office Hours, Monday through Friday, from 12:30 pm to 1:30 pm CST: Strapi Discord Open Office Hours.
For more details, visit the Strapi documentation and the Vitepress documentation.