Deploy Your VitePress Site
VitePress generates static HTML files, so you can deploy it to any static hosting service.
Building for Production
Build Command
bash
npm run docs:build
This generates static files in docs/.vitepress/dist/
which can be served by any static file server.
Build Output
docs/.vitepress/dist/
├── index.html
├── guide/
│ ├── index.html
│ └── getting-started.html
├── assets/
│ ├── style.css
│ └── app.js
└── ...
Static Hosting Platforms
Netlify
Deploy via Git
- Push your project to GitHub/GitLab
- Connect your repository to Netlify
- Configure build settings:
- Build command:
npm run docs:build
- Publish directory:
docs/.vitepress/dist
- Build command:
netlify.toml
toml
[build]
command = "npm run docs:build"
publish = "docs/.vitepress/dist"
# Redirect rules for SPA behavior
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
# Headers for better caching
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "max-age=31536000, immutable"
Vercel
Deploy via Git
- Import your project to Vercel
- Configure build settings:
- Framework Preset: Other
- Build Command:
npm run docs:build
- Output Directory:
docs/.vitepress/dist
vercel.json
json
{
"buildCommand": "npm run docs:build",
"outputDirectory": "docs/.vitepress/dist",
"trailingSlash": false,
"cleanUrls": true
}
GitHub Pages
GitHub Actions Workflow
yaml
# .github/workflows/deploy.yml
name: Deploy VitePress site to Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
cache: npm
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Install dependencies
run: npm ci
- name: Build with VitePress
run: npm run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/.vitepress/dist
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Configuration for GitHub Pages
js
// .vitepress/config.js
export default {
base: '/repository-name/', // Replace with your repo name
// ... other config
}
GitLab Pages
.gitlab-ci.yml
yaml
image: node:18
pages:
stage: deploy
cache:
paths:
- node_modules/
script:
- npm ci
- npm run docs:build
- mv docs/.vitepress/dist public
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
Cloudflare Pages
- Connect your Git repository
- Configure build settings:
- Build command:
npm run docs:build
- Build output directory:
docs/.vitepress/dist
- Node.js version: 18
- Build command:
Firebase Hosting
Setup
bash
npm install -g firebase-tools
firebase login
firebase init hosting
firebase.json
json
{
"hosting": {
"public": "docs/.vitepress/dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [
{
"source": "/assets/**",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=31536000,immutable"
}
]
}
]
}
}
Deploy
bash
npm run docs:build
firebase deploy
Server Configuration
Nginx
nginx
server {
listen 80;
server_name example.com;
root /var/www/vitepress;
index index.html;
# Handle client-side routing
location / {
try_files $uri $uri/ $uri.html /index.html;
}
# Cache static assets
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
}
Apache
apache
# .htaccess
RewriteEngine On
# Handle client-side routing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
# Cache static assets
<FilesMatch "\.(css|js|png|jpg|jpeg|gif|ico|svg)$">
ExpiresActive On
ExpiresDefault "access plus 1 year"
</FilesMatch>
Custom Domain
DNS Configuration
For custom domains, configure DNS records:
Type: CNAME
Name: www
Value: your-site.netlify.app
Type: A
Name: @
Value: [hosting provider IP]
HTTPS/SSL
Most hosting providers offer automatic HTTPS:
- Netlify: Automatic Let's Encrypt certificates
- Vercel: Automatic SSL certificates
- Cloudflare Pages: Automatic SSL
- GitHub Pages: Supports HTTPS for custom domains
Environment-Specific Configuration
Multiple Environments
js
// .vitepress/config.js
const isProd = process.env.NODE_ENV === 'production'
export default {
base: isProd ? '/production-base/' : '/',
head: isProd ? [
['script', {
async: true,
src: 'https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID'
}]
] : [],
// ... other config
}
Build Scripts
json
{
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:build:staging": "NODE_ENV=staging vitepress build docs",
"docs:preview": "vitepress preview docs"
}
}
Performance Optimization
Build Optimization
js
// .vitepress/config.js
export default {
vite: {
build: {
minify: 'terser',
rollupOptions: {
output: {
manualChunks: {
vue: ['vue'],
vendor: ['some-large-library']
}
}
}
}
}
}
Asset Optimization
- Optimize images before deployment
- Use WebP format when possible
- Enable compression (gzip/brotli)
- Implement proper caching headers
CDN Integration
js
// .vitepress/config.js
export default {
vite: {
build: {
assetsDir: 'assets',
rollupOptions: {
output: {
assetFileNames: 'assets/[name]-[hash][extname]'
}
}
}
}
}
Monitoring and Analytics
Google Analytics
js
// .vitepress/config.js
export default {
head: [
['script', {
async: true,
src: 'https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID'
}],
['script', {}, `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
`]
]
}
Error Tracking
js
// .vitepress/theme/index.js
export default {
enhanceApp({ app, router }) {
// Error tracking
app.config.errorHandler = (err, vm, info) => {
console.error('Vue error:', err, info)
// Send to error tracking service
}
// Route tracking
router.onAfterRouteChanged = (to) => {
gtag('config', 'GA_MEASUREMENT_ID', {
page_path: to
})
}
}
}
Troubleshooting
Common Issues
- 404 on Refresh: Configure server for SPA routing
- Assets Not Loading: Check base path configuration
- Build Failures: Verify Node.js version compatibility
- Slow Builds: Optimize dependencies and assets
Debug Build
bash
# Enable verbose logging
DEBUG=vitepress:* npm run docs:build
# Analyze bundle
npm run docs:build -- --debug
Best Practices
Pre-deployment Checklist
- [ ] Test build locally with
npm run docs:preview
- [ ] Verify all links work correctly
- [ ] Check responsive design
- [ ] Test performance with Lighthouse
- [ ] Validate HTML and accessibility
- [ ] Configure proper caching headers
- [ ] Set up monitoring and analytics
- [ ] Test custom domain configuration
Continuous Deployment
- Use Git-based deployment workflows
- Implement staging environments
- Set up automated testing
- Monitor deployment status
- Configure rollback procedures
Next Steps
- Configuration - Advanced configuration options
- Custom Theme - Theme customization
- Performance - Performance optimization