Blog Website
Learn how to create a modern blog website using VitePress with advanced features.
Overview
A VitePress blog is perfect for:
- Personal blogs
- Technical journals
- Company blogs
- Documentation with blog features
Key Features
📝 Content Management
- Markdown-based posts
- Frontmatter metadata
- Categories and tags
- Draft posts support
🎨 Modern Design
- Responsive layout
- Dark/light mode
- Custom themes
- Social sharing
🚀 Performance
- Static site generation
- Fast loading times
- SEO optimized
- Progressive enhancement
Project Structure
docs/
├── .vitepress/
│ ├── config.js
│ └── theme/
│ ├── index.js
│ ├── Layout.vue
│ └── components/
├── posts/
│ ├── 2024/
│ │ ├── my-first-post.md
│ │ └── vue-tips.md
│ └── index.md
├── about.md
└── index.md
Configuration
js
// .vitepress/config.js
export default {
title: 'My Blog',
description: 'A blog built with VitePress',
themeConfig: {
nav: [
{ text: 'Home', link: '/' },
{ text: 'Posts', link: '/posts/' },
{ text: 'About', link: '/about' }
],
sidebar: {
'/posts/': [
{
text: '2024',
items: [
{ text: 'My First Post', link: '/posts/2024/my-first-post' },
{ text: 'Vue Tips', link: '/posts/2024/vue-tips' }
]
}
]
},
socialLinks: [
{ icon: 'github', link: 'https://github.com/username' },
{ icon: 'twitter', link: 'https://twitter.com/username' }
]
}
}
Blog Post Template
markdown
---
title: My First Blog Post
date: 2024-01-15
author: John Doe
tags:
- vue
- javascript
- tutorial
category: Frontend
description: Learn the basics of Vue.js in this comprehensive guide
---
# {{ $frontmatter.title }}
<div class="post-meta">
<span>By {{ $frontmatter.author }}</span>
<span>{{ $frontmatter.date }}</span>
<span>Category: {{ $frontmatter.category }}</span>
</div>
Your blog content goes here...
## Introduction
Welcome to my first blog post! In this article, we'll explore...
## Main Content
### Section 1
Content for section 1...
### Section 2
Content for section 2...
## Conclusion
Thank you for reading!
---
<div class="post-tags">
<span v-for="tag in $frontmatter.tags" :key="tag" class="tag">
#{{ tag }}
</span>
</div>
Custom Theme Components
Blog Layout
vue
<!-- .vitepress/theme/Layout.vue -->
<template>
<div class="blog-layout">
<header class="blog-header">
<nav class="blog-nav">
<a href="/" class="logo">My Blog</a>
<div class="nav-links">
<a href="/posts/">Posts</a>
<a href="/about">About</a>
</div>
</nav>
</header>
<main class="blog-content">
<Content />
</main>
<footer class="blog-footer">
<p>© 2024 My Blog. All rights reserved.</p>
</footer>
</div>
</template>
<style scoped>
.blog-layout {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.blog-header {
background: var(--vp-c-bg);
border-bottom: 1px solid var(--vp-c-divider);
padding: 1rem 2rem;
}
.blog-nav {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1200px;
margin: 0 auto;
}
.logo {
font-size: 1.5rem;
font-weight: bold;
text-decoration: none;
color: var(--vp-c-brand);
}
.nav-links a {
margin-left: 2rem;
text-decoration: none;
color: var(--vp-c-text-1);
}
.blog-content {
flex: 1;
max-width: 800px;
margin: 0 auto;
padding: 2rem;
}
.blog-footer {
background: var(--vp-c-bg-soft);
text-align: center;
padding: 2rem;
color: var(--vp-c-text-2);
}
</style>
Post List Component
vue
<!-- .vitepress/theme/components/PostList.vue -->
<template>
<div class="post-list">
<article
v-for="post in posts"
:key="post.url"
class="post-item"
>
<h2>
<a :href="post.url">{{ post.title }}</a>
</h2>
<div class="post-meta">
<span>{{ formatDate(post.date) }}</span>
<span>{{ post.author }}</span>
</div>
<p class="post-excerpt">{{ post.description }}</p>
<div class="post-tags">
<span
v-for="tag in post.tags"
:key="tag"
class="tag"
>
#{{ tag }}
</span>
</div>
</article>
</div>
</template>
<script setup>
const props = defineProps({
posts: Array
})
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
}
</script>
<style scoped>
.post-list {
display: grid;
gap: 2rem;
}
.post-item {
padding: 1.5rem;
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
transition: transform 0.2s ease;
}
.post-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.post-item h2 {
margin: 0 0 0.5rem 0;
}
.post-item h2 a {
text-decoration: none;
color: var(--vp-c-text-1);
}
.post-meta {
color: var(--vp-c-text-2);
font-size: 0.9rem;
margin-bottom: 1rem;
}
.post-meta span {
margin-right: 1rem;
}
.post-excerpt {
color: var(--vp-c-text-2);
line-height: 1.6;
margin-bottom: 1rem;
}
.post-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.tag {
background: var(--vp-c-brand-soft);
color: var(--vp-c-brand);
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.8rem;
}
</style>
Advanced Features
RSS Feed Generation
js
// .vitepress/config.js
import { generateRSS } from './rss.js'
export default {
// ... other config
buildEnd: generateRSS
}
Search Integration
js
// .vitepress/config.js
export default {
themeConfig: {
search: {
provider: 'local',
options: {
detailedView: true
}
}
}
}
Comment System
vue
<!-- Add to blog post template -->
<template>
<div class="comments">
<h3>Comments</h3>
<!-- Integrate with services like Disqus, Giscus, etc. -->
</div>
</template>
SEO Optimization
Meta Tags
markdown
---
title: My Blog Post
description: A comprehensive guide to building blogs with VitePress
head:
- - meta
- property: og:title
content: My Blog Post
- - meta
- property: og:description
content: A comprehensive guide to building blogs with VitePress
- - meta
- property: og:image
content: /images/blog-post-cover.jpg
---
Sitemap Generation
js
// .vitepress/config.js
export default {
sitemap: {
hostname: 'https://myblog.com'
}
}
Deployment
Netlify
toml
# netlify.toml
[build]
command = "npm run docs:build"
publish = "docs/.vitepress/dist"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
Vercel
json
{
"buildCommand": "npm run docs:build",
"outputDirectory": "docs/.vitepress/dist"
}
Best Practices
Content Organization
- Use consistent frontmatter
- Organize posts by date or category
- Create meaningful URLs
- Add proper meta descriptions
Performance
- Optimize images
- Use lazy loading
- Minimize JavaScript
- Enable compression
User Experience
- Responsive design
- Fast navigation
- Clear typography
- Accessible markup