Skip to content

主题配置

文章目录

默认情况下,主题默认会在您指定的根目录下取去寻找 posts 目录,并将目录下的所有 .md 文件视为文章进行加载。可修改 postDir 自定义文章目录

ts
export default defineConfig({
	themeConfig: {
		postDir: 'posts', 
	},
});
export default defineConfig({
	themeConfig: {
		postDir: 'posts', 
	},
});

注意

vitepress 中存在根目录和源目录,默认情况下两者是相等的,如果您对 srcDir 进行了修改,则也同时需要对 postDir 进行修改。 v0.0.12 后版本数据加载自动获取 srcDir 目录进行同步

了解根目录和源目录的区别 请看这里

路由重写

postDirposts 情况下,博客目录结构和生成后路径如下:

.
├─ posts
│  ├─ test.md
│  └─ demo.md
.
├─ posts
│  ├─ test.md
│  └─ demo.md
posts/test.md  -->  /posts/test.html  -->  https://xxx.xx/posts/test.html
posts/demo.md  -->  /posts/demo.html  -->  https://xxx.xx/posts/demo.html
posts/test.md  -->  /posts/test.html  -->  https://xxx.xx/posts/test.html
posts/demo.md  -->  /posts/demo.html  -->  https://xxx.xx/posts/demo.html

如果想路径上不需要带 posts 可以设置 rewritePosttrue

ts
export default defineConfig({
	themeConfig: {
		rewritePost: true 
	},
});
//等效于
export default defineConfig({
	rewrites: {
		'posts/(.*)': '(.*)' 
	},
});
export default defineConfig({
	themeConfig: {
		rewritePost: true 
	},
});
//等效于
export default defineConfig({
	rewrites: {
		'posts/(.*)': '(.*)' 
	},
});
posts/test.md  -->  /test.html  -->  https://xxx.xx/test.html
posts/demo.md  -->  /demo.html  -->  https://xxx.xx/demo.html
posts/test.md  -->  /test.html  -->  https://xxx.xx/test.html
posts/demo.md  -->  /demo.html  -->  https://xxx.xx/demo.html

如果还有其他路由需要重写,可以参考 vitepress 的 路由重写

主题语言

主题内置文本语言切换,支持 zh-Hansen,修改 vitepress 配置中 lang 即可切换。

ts
export default defineConfig({
	lang: "en",
});
export default defineConfig({
	lang: "en",
});

自定义语言

可以通过 languages 字段配置,覆盖默认文字。

当然也可以定义一种新的语言。

ts
export default defineConfig({
	lang: "en",
	themeConfig: {
		languages: {
			en: {
				title: 'Site Information',
			}
		}
	}
});
export default defineConfig({
	lang: "en",
	themeConfig: {
		languages: {
			en: {
				title: 'Site Information',
			}
		}
	}
});
ts
/** 语言文件 */
interface Language {
	site: {
		title: string;
		webmaster: string;
		domain: string;
		avatar: string;
		describe: string;
		ruleText: string;
		contactMe: string;
	};

	// 页面模块小标题
	title: {
		links: string;
		newPublish: string;
		comment: string;
		author: string;
		blog: string;
		privacy: string;
		more: string;
		allArchives: string;
		yearArchives: string;
		otherArticles: string;
		unclassified: string;
	};

	// 菜单
	menu: {
		home: string;
		categorys: string;
		archives: string;
		tags: string;
		links: string;
		about: string;
	};

	// 标题栏
	favicon: {
		showText: string;
		hideText: string;
	};

	// 文章内容
	post: {
		sticky: string;
		rewardComment: string;
		noticeOutdateMessage: string;
		copyright: {
			author: string;
			link: string;
			licenseTitle: string;
			licenseContent: string;
		};
	};

	// 按钮块
	rightside: {
		search: string;
		backToTop: string;
		toc: string;
		theme: {
			dark: string;
			light: string;
		};
		aside: {
			open: string;
			exit: string;
		};
		readMode: {
			open: string;
			exit: string;
		};
	};

	// 页脚
	footer: {
		powered: string;
		theme: string;
		tips: string;
		day: string;
		hour: string;
		minute: string;
		seconds: string;
	};

	// 符号
	symbol: {
		comma: string;
		period: string;
		colon: string;
	};

	// 404
	notFound: {
		title: string;
		text: string;
		name: string;
	};
}
/** 语言文件 */
interface Language {
	site: {
		title: string;
		webmaster: string;
		domain: string;
		avatar: string;
		describe: string;
		ruleText: string;
		contactMe: string;
	};

	// 页面模块小标题
	title: {
		links: string;
		newPublish: string;
		comment: string;
		author: string;
		blog: string;
		privacy: string;
		more: string;
		allArchives: string;
		yearArchives: string;
		otherArticles: string;
		unclassified: string;
	};

	// 菜单
	menu: {
		home: string;
		categorys: string;
		archives: string;
		tags: string;
		links: string;
		about: string;
	};

	// 标题栏
	favicon: {
		showText: string;
		hideText: string;
	};

	// 文章内容
	post: {
		sticky: string;
		rewardComment: string;
		noticeOutdateMessage: string;
		copyright: {
			author: string;
			link: string;
			licenseTitle: string;
			licenseContent: string;
		};
	};

	// 按钮块
	rightside: {
		search: string;
		backToTop: string;
		toc: string;
		theme: {
			dark: string;
			light: string;
		};
		aside: {
			open: string;
			exit: string;
		};
		readMode: {
			open: string;
			exit: string;
		};
	};

	// 页脚
	footer: {
		powered: string;
		theme: string;
		tips: string;
		day: string;
		hour: string;
		minute: string;
		seconds: string;
	};

	// 符号
	symbol: {
		comma: string;
		period: string;
		colon: string;
	};

	// 404
	notFound: {
		title: string;
		text: string;
		name: string;
	};
}

主题模式

参考 vitepress 配置。

网站图标

用于 logo、icon、安装图标配置,通过 favicon 字段配置。

ts
export default defineConfig({
	themeConfig: {
		favicon: { 
			logo: '/favicon.svg', 
			icon16: '/favicon.svg', 
			icon32: '/favicon.svg' 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		favicon: { 
			logo: '/favicon.svg', 
			icon16: '/favicon.svg', 
			icon32: '/favicon.svg' 
		} 
	}
});
ts
/**
 * 网站图标配置 || Configure the icon information of the blog
 */
interface FaviconConfig {
	/**
	 * logo
	 */
	logo?: string;
	/**
	 *  dark 下使用
	 */
	darkLogo?: string;
	/**
	 * 网站图标
	 */
	icon16?: string;
	/**
	 * 网站图标
	 */
	icon32?: string;
	/**
	 * iOS 添加到主屏幕使用图标
	 */
	appleTouchIcon?: string;
	/**
	 * 网站清单配置
	 */
	webmanifest?: string;
	/**
	 * 是否监听选项卡可见事件
	 */
	visibilitychange?: boolean;
	/**
	 * 选项卡不可见时显示角标
	 */
	hidden?: string;
	/**
	 * 选项卡不可见 显示文案
	 */
	showText?: string;
	/**
	 * 选项卡由不可见切换为可见时显示文案
	 */
	hideText?: string;
}
/**
 * 网站图标配置 || Configure the icon information of the blog
 */
interface FaviconConfig {
	/**
	 * logo
	 */
	logo?: string;
	/**
	 *  dark 下使用
	 */
	darkLogo?: string;
	/**
	 * 网站图标
	 */
	icon16?: string;
	/**
	 * 网站图标
	 */
	icon32?: string;
	/**
	 * iOS 添加到主屏幕使用图标
	 */
	appleTouchIcon?: string;
	/**
	 * 网站清单配置
	 */
	webmanifest?: string;
	/**
	 * 是否监听选项卡可见事件
	 */
	visibilitychange?: boolean;
	/**
	 * 选项卡不可见时显示角标
	 */
	hidden?: string;
	/**
	 * 选项卡不可见 显示文案
	 */
	showText?: string;
	/**
	 * 选项卡由不可见切换为可见时显示文案
	 */
	hideText?: string;
}

用户信息

用户基本信息,用于博主名称、头像、友链交换规则等等,通过 user 字段配置。

ts
export default defineConfig({
	themeConfig: {
		user: { 
			//... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		user: { 
			//... 
		} 
	}
});
ts
/**
 * 用户配置 || User config
 */
interface UserConfig {
	/**
	 * 站点昵称
	 */
	name?: string;
	/**
	 * 名 - 用于顶部左侧 logo 边文字组成
	 */
	firstName?: string;
	/**
	 * 姓  - 用于顶部左侧 logo 边文字组成
	 */
	lastName?: string;
	/**
	 * 邮箱
	 */
	email?: string;
	/**
	 * 域名
	 */
	domain?: string;
	/**
	 * 头像
	 */
	avatar?: string;
	/**
	 * dark 下使用
	 */
	darkAvatar?: string;
	/**
	 * 站点简介
	 */
	describe?: string;
	/**
	 * 友情链接规则
	 */
	ruleText?: string;
}
/**
 * 用户配置 || User config
 */
interface UserConfig {
	/**
	 * 站点昵称
	 */
	name?: string;
	/**
	 * 名 - 用于顶部左侧 logo 边文字组成
	 */
	firstName?: string;
	/**
	 * 姓  - 用于顶部左侧 logo 边文字组成
	 */
	lastName?: string;
	/**
	 * 邮箱
	 */
	email?: string;
	/**
	 * 域名
	 */
	domain?: string;
	/**
	 * 头像
	 */
	avatar?: string;
	/**
	 * dark 下使用
	 */
	darkAvatar?: string;
	/**
	 * 站点简介
	 */
	describe?: string;
	/**
	 * 友情链接规则
	 */
	ruleText?: string;
}

顶部导航

导航栏右侧菜单配置,通过 topBars 字段配置。

左侧 logo 在网站图标中进行配置。

ts
export default defineConfig({
	themeConfig: {
		topBars: [ 
			{ title: 'Home', url: '/' }, 
			{ 
				title: 'Demo', 
				children: [ 
					{ title: '归档', url: '/archives' }, 
				], 
			} 
		] 
	}
});
export default defineConfig({
	themeConfig: {
		topBars: [ 
			{ title: 'Home', url: '/' }, 
			{ 
				title: 'Demo', 
				children: [ 
					{ title: '归档', url: '/archives' }, 
				], 
			} 
		] 
	}
});
ts
/** 导航栏链接 */
interface NavItemWithLink {
	/**
	 * 标题
	 */
	title: string;
	/**
	 * 链接
	 */
	url: string;
	/**
	 * 激活匹配规则
	 * `activeMatch` is expected to be a regex string. We can't use actual
	 * RegExp object here because it isn't serializable
	 */
	activeMatch?: string;
	/**
	 * 打开方式
	 */
	target?: string;
	/**
	 * HTML rel
	 */
	rel?: string;
	/**
	 * 子级
	 */
	children?: never;
}

interface NavItemWithChildren {
	/**
	 * 标题
	 */
	title: string;
	/**
	 * 链接
	 */
	url?: string;
	/**
	 * 激活匹配规则
	 * `activeMatch` is expected to be a regex string. We can't use actual
	 * RegExp object here because it isn't serializable
	 */
	activeMatch?: string;
	/**
	 * 打开方式
	 */
	target?: string;
	/**
	 * HTML rel
	 */
	rel?: string;
	/**
	 * 子级
	 */
	children: NavItemWithLink[];
}
/** 导航栏链接 */
interface NavItemWithLink {
	/**
	 * 标题
	 */
	title: string;
	/**
	 * 链接
	 */
	url: string;
	/**
	 * 激活匹配规则
	 * `activeMatch` is expected to be a regex string. We can't use actual
	 * RegExp object here because it isn't serializable
	 */
	activeMatch?: string;
	/**
	 * 打开方式
	 */
	target?: string;
	/**
	 * HTML rel
	 */
	rel?: string;
	/**
	 * 子级
	 */
	children?: never;
}

interface NavItemWithChildren {
	/**
	 * 标题
	 */
	title: string;
	/**
	 * 链接
	 */
	url?: string;
	/**
	 * 激活匹配规则
	 * `activeMatch` is expected to be a regex string. We can't use actual
	 * RegExp object here because it isn't serializable
	 */
	activeMatch?: string;
	/**
	 * 打开方式
	 */
	target?: string;
	/**
	 * HTML rel
	 */
	rel?: string;
	/**
	 * 子级
	 */
	children: NavItemWithLink[];
}

侧栏信息

包含 社交图标、打字动画、侧栏信息配置,通过 sidebar 字段配置。

社交图标

ts
export default defineConfig({
	themeConfig: {
		sidebar: {
			social: [  
				{  
					name: 'vue',  
					url: 'https://cn.vuejs.org/',  
					icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`,  
				},  
			],  
		}
	}
});
export default defineConfig({
	themeConfig: {
		sidebar: {
			social: [  
				{  
					name: 'vue',  
					url: 'https://cn.vuejs.org/',  
					icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`,  
				},  
			],  
		}
	}
});
ts
/**
 * 侧栏配置 || Layout sidebar config
 */
interface SidebarConfig {
	/**
	 * 打字动画固定前缀
	 */
	typedTextPrefix?: string;
	/**
	 * 打字动画切换文案
	 */
	typedText?: string[];
	/**
	 * 个人信息
	 */
	info?: {
		key: string;
		val: string;
	}[];
	/**
	 * 社交地址图标链接
	 */
	social?: {
		/**
		 * 名称
		 */
		name: string;
		/**
		 * svg  eg: icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`
		 */
		icon: string;
		/**
		 * 链接
		 */
		url: string;
	}[];
}
/**
 * 侧栏配置 || Layout sidebar config
 */
interface SidebarConfig {
	/**
	 * 打字动画固定前缀
	 */
	typedTextPrefix?: string;
	/**
	 * 打字动画切换文案
	 */
	typedText?: string[];
	/**
	 * 个人信息
	 */
	info?: {
		key: string;
		val: string;
	}[];
	/**
	 * 社交地址图标链接
	 */
	social?: {
		/**
		 * 名称
		 */
		name: string;
		/**
		 * svg  eg: icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`
		 */
		icon: string;
		/**
		 * 链接
		 */
		url: string;
	}[];
}

打字动画

ts
export default defineConfig({
	themeConfig: {
		sidebar: {
			typedText: ['Web Developer', 'UI Designer'], 
			social: [
				{
					name: 'vue',
					url: 'https://cn.vuejs.org/',
					icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`,
				},
			],
		}
	}
});
export default defineConfig({
	themeConfig: {
		sidebar: {
			typedText: ['Web Developer', 'UI Designer'], 
			social: [
				{
					name: 'vue',
					url: 'https://cn.vuejs.org/',
					icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`,
				},
			],
		}
	}
});
ts
/**
 * 侧栏配置 || Layout sidebar config
 */
interface SidebarConfig {
	/**
	 * 打字动画固定前缀
	 */
	typedTextPrefix?: string;
	/**
	 * 打字动画切换文案
	 */
	typedText?: string[];
	/**
	 * 个人信息
	 */
	info?: {
		key: string;
		val: string;
	}[];
	/**
	 * 社交地址图标链接
	 */
	social?: {
		/**
		 * 名称
		 */
		name: string;
		/**
		 * svg  eg: icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`
		 */
		icon: string;
		/**
		 * 链接
		 */
		url: string;
	}[];
}
/**
 * 侧栏配置 || Layout sidebar config
 */
interface SidebarConfig {
	/**
	 * 打字动画固定前缀
	 */
	typedTextPrefix?: string;
	/**
	 * 打字动画切换文案
	 */
	typedText?: string[];
	/**
	 * 个人信息
	 */
	info?: {
		key: string;
		val: string;
	}[];
	/**
	 * 社交地址图标链接
	 */
	social?: {
		/**
		 * 名称
		 */
		name: string;
		/**
		 * svg  eg: icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`
		 */
		icon: string;
		/**
		 * 链接
		 */
		url: string;
	}[];
}

侧栏信息

ts
export default defineConfig({
	themeConfig: {
		sidebar: {
			typedText: ['Web Developer', 'UI Designer'],
			social: [
				{
					name: 'vue',
					url: 'https://cn.vuejs.org/',
					icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`,
				},
			],
			info: [ 
				{ 
					key: '地址', 
					val: '中国' 
				} 
			] 
		}
	}
});
export default defineConfig({
	themeConfig: {
		sidebar: {
			typedText: ['Web Developer', 'UI Designer'],
			social: [
				{
					name: 'vue',
					url: 'https://cn.vuejs.org/',
					icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`,
				},
			],
			info: [ 
				{ 
					key: '地址', 
					val: '中国' 
				} 
			] 
		}
	}
});
ts
/**
 * 侧栏配置 || Layout sidebar config
 */
interface SidebarConfig {
	/**
	 * 打字动画固定前缀
	 */
	typedTextPrefix?: string;
	/**
	 * 打字动画切换文案
	 */
	typedText?: string[];
	/**
	 * 个人信息
	 */
	info?: {
		key: string;
		val: string;
	}[];
	/**
	 * 社交地址图标链接
	 */
	social?: {
		/**
		 * 名称
		 */
		name: string;
		/**
		 * svg  eg: icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`
		 */
		icon: string;
		/**
		 * 链接
		 */
		url: string;
	}[];
}
/**
 * 侧栏配置 || Layout sidebar config
 */
interface SidebarConfig {
	/**
	 * 打字动画固定前缀
	 */
	typedTextPrefix?: string;
	/**
	 * 打字动画切换文案
	 */
	typedText?: string[];
	/**
	 * 个人信息
	 */
	info?: {
		key: string;
		val: string;
	}[];
	/**
	 * 社交地址图标链接
	 */
	social?: {
		/**
		 * 名称
		 */
		name: string;
		/**
		 * svg  eg: icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z"/></svg>`
		 */
		icon: string;
		/**
		 * 链接
		 */
		url: string;
	}[];
}

横幅信息

每个页面横幅都可以自定义不同背景图、标语等,当您需要视频背景的时候,您的视频格式需要为 MP4、WebM 、Ogg 等格式。

配置中的 banner 设置为全局的,如果想在不同页面设置不同 banner,可以在 .md 文件 Frontmatter 上设置。

ts
export default defineConfig({
	themeConfig: {
		banner: { 
			type: 'img', 
			bgurl: 'xxx/xx.png', 
			bannerTitle: 'Hello word', 
			bannerText: '', 
			// ...  
		} 
	}
});
export default defineConfig({
	themeConfig: {
		banner: { 
			type: 'img', 
			bgurl: 'xxx/xx.png', 
			bannerTitle: 'Hello word', 
			bannerText: '', 
			// ...  
		} 
	}
});
ts
/**
 * 横幅配置 || Layout banner config
 */
interface BannerConfig {
	/**
	 * 横幅类型
	 */
	type?: 'img' | 'video';
	/**
	 * 横幅资源路径地址
	 */
	bgurl?: string;
	/**
	 * 横幅标题
	 */
	bannerTitle?: string;
	/**
	 * 横幅描述
	 */
	bannerText?: string;
	/**
	 * 同 CSS object-position
	 */
	position?: string;
	/**
	 * 同 CSS object-fit
	 */
	fit?: string;
}
/**
 * 横幅配置 || Layout banner config
 */
interface BannerConfig {
	/**
	 * 横幅类型
	 */
	type?: 'img' | 'video';
	/**
	 * 横幅资源路径地址
	 */
	bgurl?: string;
	/**
	 * 横幅标题
	 */
	bannerTitle?: string;
	/**
	 * 横幅描述
	 */
	bannerText?: string;
	/**
	 * 同 CSS object-position
	 */
	position?: string;
	/**
	 * 同 CSS object-fit
	 */
	fit?: string;
}

页脚信息

页脚所有配置预览:

ts
export default defineConfig({
	themeConfig: {
		footer: { 
			// ...  
		} 
	}
});
export default defineConfig({
	themeConfig: {
		footer: { 
			// ...  
		} 
	}
});
ts
/**
 * 页脚配置 || Layout footer config
 */
interface FooterConfig {
	/**
	 * 是否显示 vitepress 和 主题
	 * theme link (Powered by vitepress).
	 */
	powered?: {
		enable: boolean;
	};
	/**
	 * 备案信息
	 * Beian icp information for Chinese users. In China, every legal website should have a beian icp in website footer.
	 * https://beian.miit.gov.cn/
	 */
	beian?: {
		enable: boolean;
		icp?: string;
	};
	/**
	 * 版权开始年号
	 */
	copyrightYear?: string;
	/**
	 * 运行时长
	 */
	liveTime?: {
		enable?: boolean;
		/**
		 * 前缀
		 */
		prefix?: string;
		/**
		 * 运行计算开始时间
		 */
		startTime?: string;
	};
}
/**
 * 页脚配置 || Layout footer config
 */
interface FooterConfig {
	/**
	 * 是否显示 vitepress 和 主题
	 * theme link (Powered by vitepress).
	 */
	powered?: {
		enable: boolean;
	};
	/**
	 * 备案信息
	 * Beian icp information for Chinese users. In China, every legal website should have a beian icp in website footer.
	 * https://beian.miit.gov.cn/
	 */
	beian?: {
		enable: boolean;
		icp?: string;
	};
	/**
	 * 版权开始年号
	 */
	copyrightYear?: string;
	/**
	 * 运行时长
	 */
	liveTime?: {
		enable?: boolean;
		/**
		 * 前缀
		 */
		prefix?: string;
		/**
		 * 运行计算开始时间
		 */
		startTime?: string;
	};
}

驱动

自豪地显示当前使用的博客框架 Vitepress 与主题 Async 的名字及版本。

如:由 Vitepress 驱动 v1.0.0-rc.24 | 主题 - Async v0.0.5

让更多人知道 Vitepress 与主题 Vitepress-Theme-Async,这有利于开源社区进一步发展。

ts
export default defineConfig({
	themeConfig: {
		footer: {
			powered: {
				enable: true
			}
			// ...
		}
	}
});
export default defineConfig({
	themeConfig: {
		footer: {
			powered: {
				enable: true
			}
			// ...
		}
	}
});

备案

国内用户可以提供备案号,开启备案显示。

备案信息默认链接为:https://beian.miit.gov.cn/

ts
export default defineConfig({
	themeConfig: {
		footer: {
			beian: {
				enable: true
				icp: 'ICP xxxxxx'
			}
			// ...
		}
	}
});
export default defineConfig({
	themeConfig: {
		footer: {
			beian: {
				enable: true
				icp: 'ICP xxxxxx'
			}
			// ...
		}
	}
});

运行时间

默认关闭。示例: 本博客已萌萌哒地运行 442 天

ts
export default defineConfig({
	themeConfig: {
		footer: {
			liveTime: {
				enable: true
				startTime: '2023/10/01' 
			}
			// ...
		}
	}
});
export default defineConfig({
	themeConfig: {
		footer: {
			liveTime: {
				enable: true
				startTime: '2023/10/01' 
			}
			// ...
		}
	}
});

文章详情

这里是一些关于文章相关配置合集。

打赏

通过 reward 字段配置,开启后,将在每篇文章 post 末尾显示打赏按钮。

ts
export default defineConfig({
	themeConfig: {
		reward: { 
			... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		reward: { 
			... 
		} 
	}
});
ts
/**
 * 打赏配置 || Reward config
 */
interface RewardConfig {
	/**
	 * 是否显示打赏按钮
	 */
	enable?: boolean;
	/**
	 * 打赏按钮下的描述
	 */
	comment?: string;
	/**
	 * 打赏链接(当开启打赏链接时,将自动跳转您的外部链接而不是展开二维码)
	 */
	url?: string;
	/**
	 * 打赏二维码
	 */
	methods?: {
		/**
		 * 二维码地址
		 */
		path: string;
		/**
		 * 二维码描述
		 */
		name: string;
		/**
		 * 点击二维码跳转链接
		 */
		link?: string;
	}[];
}
/**
 * 打赏配置 || Reward config
 */
interface RewardConfig {
	/**
	 * 是否显示打赏按钮
	 */
	enable?: boolean;
	/**
	 * 打赏按钮下的描述
	 */
	comment?: string;
	/**
	 * 打赏链接(当开启打赏链接时,将自动跳转您的外部链接而不是展开二维码)
	 */
	url?: string;
	/**
	 * 打赏二维码
	 */
	methods?: {
		/**
		 * 二维码地址
		 */
		path: string;
		/**
		 * 二维码描述
		 */
		name: string;
		/**
		 * 点击二维码跳转链接
		 */
		link?: string;
	}[];
}

版权信息

设置您的文章的分享版权

关于许可协议 默认使用 署名-非商业性使用-相同方式共享 4.0,即 CC BY-NC-SA 4.0

通过 creativeCommons 字段配置

ts
export default defineConfig({
	themeConfig: {
		creativeCommons: { 
			... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		creativeCommons: { 
			... 
		} 
	}
});
ts
/**
 * 文章版权信息 || Creative commons config
 */
interface CreativeCommonsConfig {
	/**
	 * 设置证书 (by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | zero)
	 */
	license?: string;
	/**
	 * 设置语言 (deed.zh-hans | deed.en | deed.ja | ...)
	 */
	language?: string;
	/**
	 * 在每篇文章末尾显示
	 */
	post?: boolean;
	/**
	 * 是否在复制文章时,在剪贴板中追加版权信息(默认关闭)
	 */
	clipboard?: boolean;
}
/**
 * 文章版权信息 || Creative commons config
 */
interface CreativeCommonsConfig {
	/**
	 * 设置证书 (by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | zero)
	 */
	license?: string;
	/**
	 * 设置语言 (deed.zh-hans | deed.en | deed.ja | ...)
	 */
	language?: string;
	/**
	 * 在每篇文章末尾显示
	 */
	post?: boolean;
	/**
	 * 是否在复制文章时,在剪贴板中追加版权信息(默认关闭)
	 */
	clipboard?: boolean;
}

上下篇

文章详情页中上下篇配置,通过 postPagination 字段配置

ts
export default defineConfig({
	themeConfig: {
		postPagination: { 
			... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		postPagination: { 
			... 
		} 
	}
});
ts
/**
 * 文章上下页 || the upper and lower pages of the article
 */
interface PostPaginationConfig {
	/**
	 * 文章底部是否显示上下篇
	 */
	enable?: boolean;
	/**
	 * 上下篇卡片样式
	 */
	type?: 'large' | 'small';
}
/**
 * 文章上下页 || the upper and lower pages of the article
 */
interface PostPaginationConfig {
	/**
	 * 文章底部是否显示上下篇
	 */
	enable?: boolean;
	/**
	 * 上下篇卡片样式
	 */
	type?: 'large' | 'small';
}

文章封面

通过配置 cover 字段,来选择默认文章封面样式

ts
export default defineConfig({
	themeConfig: {
		cover: { 
			... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		cover: { 
			... 
		} 
	}
});
ts
/**
 * 文章封面图 || Post cover image
 */
interface ConverConfig {
	default?: string;
	type?: 'img' | 'date' | 'random';
}
/**
 * 文章封面图 || Post cover image
 */
interface ConverConfig {
	default?: string;
	type?: 'img' | 'date' | 'random';
}

过期提醒

通过配置 noticeOutdate 字段使用,enabletrue 时,会根据文章发布时间计算已经过去多少天,如果超出 limitDay 配置天数,则会显示过期提醒标识

ts
export default defineConfig({
	themeConfig: {
		noticeOutdate: { 
			... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		noticeOutdate: { 
			... 
		} 
	}
});
ts
/**
 * 过期提取 || notice outdate
 */
interface NoticeOutdateConfig {
	/**
	 * 是否启用
	 */
	enable?: boolean;
	/**
	 * 样式
	 */
	style?: 'simple' | 'flat';
	/**
	 * 距离今天多少天时显示
	 */
	limitDay?: number;
	/**
	 * 显示在文章中位置
	 */
	position?: 'top' | 'bottom';
}
/**
 * 过期提取 || notice outdate
 */
interface NoticeOutdateConfig {
	/**
	 * 是否启用
	 */
	enable?: boolean;
	/**
	 * 样式
	 */
	style?: 'simple' | 'flat';
	/**
	 * 距离今天多少天时显示
	 */
	limitDay?: number;
	/**
	 * 显示在文章中位置
	 */
	position?: 'top' | 'bottom';
}

破图配置

您可以添加图片加载失败时显示默认图片,通过配置 errorImg 字段使用。

ts
export default defineConfig({
	themeConfig: {
		errorImg: { 
			... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		errorImg: { 
			... 
		} 
	}
});
ts
/**
 * 破图时默认图片
 */
interface ErrorImgConfig {
	/**
	 * 友链头像破图时显示默认图片
	 */
	flink?: string;
	/**
	 * 文章破图时显示默认图片
	 */
	postPage?: string;
}
/**
 * 破图时默认图片
 */
interface ErrorImgConfig {
	/**
	 * 友链头像破图时显示默认图片
	 */
	flink?: string;
	/**
	 * 文章破图时显示默认图片
	 */
	postPage?: string;
}

其他配置

固定按钮

右下角按钮区域部分按钮配置,通过 rightside 字段配置

ts
export default defineConfig({
	themeConfig: {
		rightside: { 
			... 
		} 
	}
});
export default defineConfig({
	themeConfig: {
		rightside: { 
			... 
		} 
	}
});
ts
/**
 * 固定按钮显示配置 || Fixed button config on the right
 */
interface FixedBtnConfig {
	/**
	 * 阅读模式按钮
	 */
	readmode?: boolean;
	/**
	 * 单双栏切换按钮
	 */
	aside?: boolean;
}
/**
 * 固定按钮显示配置 || Fixed button config on the right
 */
interface FixedBtnConfig {
	/**
	 * 阅读模式按钮
	 */
	readmode?: boolean;
	/**
	 * 单双栏切换按钮
	 */
	aside?: boolean;
}

分页规则

首页和归档分页可单独配置,分为 indexGeneratorarchiveGenerator

默认情况下都是按每页 10 篇,日期倒叙进行分页。

首页分页

ts
export default defineConfig({
	themeConfig: {
		indexGenerator: {
			perPage: 8, 
		}
	}
});
export default defineConfig({
	themeConfig: {
		indexGenerator: {
			perPage: 8, 
		}
	}
});
ts
/**
 * 页面分页配置 || [index | archives | categorys | tags] page sort paging config
 */
interface IndexGeneratorConfig {
	/**
	 * 分页大小
	 */
	perPage?: number;
	/**
	 * 排序方式
	 */
	orderBy?: string;
	/**
	 * 分页是否生成静态文件
	 */
	static?: boolean;
}
/**
 * 页面分页配置 || [index | archives | categorys | tags] page sort paging config
 */
interface IndexGeneratorConfig {
	/**
	 * 分页大小
	 */
	perPage?: number;
	/**
	 * 排序方式
	 */
	orderBy?: string;
	/**
	 * 分页是否生成静态文件
	 */
	static?: boolean;
}

默认情况下,生成的分页是伪分页,通过 URL 参数前端实现的分页,并不会按照分页生成对应 .html 文件。

如果需要按分页生成静态文件需要开启 static 配置,然后将 index.md 改名为 [index].md,并添加 [index].paths.ts 文件,调用主题 dynamicPages 方法动态添加分页路由。

ts
export default defineConfig({
	themeConfig: {
		indexGenerator: {
			static: true, 
		}
	}
});
export default defineConfig({
	themeConfig: {
		indexGenerator: {
			static: true, 
		}
	}
});
txt
.
├─ .vitepress
├─ posts
│  └─ ...
├─ index.md 
├─ [index].md 
├─ [index].paths.ts 
├─ ...
.
├─ .vitepress
├─ posts
│  └─ ...
├─ index.md 
├─ [index].md 
├─ [index].paths.ts 
├─ ...
ts
import { dynamicPages } from 'vitepress-theme-async/plugin/page';
import config from './.vitepress/config';

export default {
	async paths() {
		return dynamicPages(config, 'index');
	},
};
import { dynamicPages } from 'vitepress-theme-async/plugin/page';
import config from './.vitepress/config';

export default {
	async paths() {
		return dynamicPages(config, 'index');
	},
};
txt
# 静态模式访问路径
https://xxx				// 首页
https://xxx/page/2		// 第二页
https://xxx/page/3		// 第三页

# 普通模式访问路径
https://xxx				// 首页
https://xxx?page=2		// 第二页
https://xxx?page=3		// 第三页
# 静态模式访问路径
https://xxx				// 首页
https://xxx/page/2		// 第二页
https://xxx/page/3		// 第三页

# 普通模式访问路径
https://xxx				// 首页
https://xxx?page=2		// 第二页
https://xxx?page=3		// 第三页

归档分页

归档分配置后,同时也会对分类页标签页生效。

除了设置分页外,还可以对归档时间轴卡片样式和归档日期格式进行配置。

ts
export default defineConfig({
	themeConfig: {
		archiveGenerator: {
			style: 'less', 
		}
	}
});
export default defineConfig({
	themeConfig: {
		archiveGenerator: {
			style: 'less', 
		}
	}
});
ts
/**
 * 归档页生成和配置
 */
interface ArchiveGeneratorConfig extends AsyncTheme.IndexGeneratorConfig {
	/**
	 * 归档页时间轴卡片样式 */
	style?: 'less' | 'more';
	/**
	 * 归档时日期格式
	 */
	dateFmt?: string;
}
/**
 * 归档页生成和配置
 */
interface ArchiveGeneratorConfig extends AsyncTheme.IndexGeneratorConfig {
	/**
	 * 归档页时间轴卡片样式 */
	style?: 'less' | 'more';
	/**
	 * 归档时日期格式
	 */
	dateFmt?: string;
}

归档分类页与首页一样,默认情况下,生成的分页是伪分页,通过 URL 参数前端实现的分页,并不会按照分页生成对应 .html 文件。

如果需要按分页生成静态文件需要开启 static 配置,然后将 archives|categories|tags.md 改名为 [archives|categories|tags].md,并添加 [archives|categories|tags].paths.ts 文件,调用主题 dynamicPages 方法动态添加分页路由。

ts
export default defineConfig({
	themeConfig: {
		archiveGenerator: {
			static: true, 
		}
	}
});
export default defineConfig({
	themeConfig: {
		archiveGenerator: {
			static: true, 
		}
	}
});
txt
.
├─ .vitepress
├─ posts
│  └─ ...
├─ archives.md 
├─ [archives].md 
├─ [archives].paths.ts 
├─ categories.md 
├─ [categories].md 
├─ [categories].paths.ts 
├─ tags.md 
├─ [tags].md 
├─ [tags].paths.ts 
├─ ...
.
├─ .vitepress
├─ posts
│  └─ ...
├─ archives.md 
├─ [archives].md 
├─ [archives].paths.ts 
├─ categories.md 
├─ [categories].md 
├─ [categories].paths.ts 
├─ tags.md 
├─ [tags].md 
├─ [tags].paths.ts 
├─ ...

如果开启了分页生成静态文件,文件的路由会根据 page 配置生成路由,以 tags 为例

配置路径第一页路径其他页路径子级第一页子级其他页路径
//index.html/page/2.html/子级.html/子级/page/2.html
/index/index.html/page/2.html/子级.html/子级/page/2.html
/tags/tags.html/tags/page/2.html/tags/子级.html/tags/子级/page/2.html
/tags//tags/index.html/tags/page/2.html/tags/子级.html/tags/子级/page/2.html
/tags/index/tags/index.html/tags/page/2.html/tags/子级.html/tags/子级/page/2.html

分类卡片

首页中显示的分类卡片。

默认情况下,会显示分类里文章最多的两个,您可以通过修改配置来替换默认行为。

ts
export default defineConfig({
	themeConfig: {
		categorieCard: { 
			list: ["分类1", "分类2"], 
			// ...  
		} 
	}
});
export default defineConfig({
	themeConfig: {
		categorieCard: { 
			list: ["分类1", "分类2"], 
			// ...  
		} 
	}
});
ts
/**
 * 首页中显示的分类卡片
 */
interface CategorieCardConfig {
	/**
	 * 是否启用
	 */
	enable?: boolean;
	/**
	 * 需要显示分类数量,默认为 2 个
	 */
	len?: number;
	/**
	 * 固定显示分类
	 */
	list?: string[];
}
/**
 * 首页中显示的分类卡片
 */
interface CategorieCardConfig {
	/**
	 * 是否启用
	 */
	enable?: boolean;
	/**
	 * 需要显示分类数量,默认为 2 个
	 */
	len?: number;
	/**
	 * 固定显示分类
	 */
	list?: string[];
}

RSS 配置

内置 RSS 生成插件,使用 Feed 生成,默认关闭。

开启后,会更具 fileName (默认为 feed.rss) 生成不同类型格式。

  • .xml => atom1
  • .json => json1
  • .rss => rss2
ts
export default defineConfig({
	themeConfig: {
		rss: { 
			enable: true, 
			// ...  
		} 
	}
});
export default defineConfig({
	themeConfig: {
		rss: { 
			enable: true, 
			// ...  
		} 
	}
});
ts
/**
 * RSS 生成
 */
interface RSSConfig {
	/**
	 * 是否启用
	 */
	enable?: boolean;
	/**
	 * 你的站点地址 eg: https://www.imalun.com
	 */
	baseUrl: string;
	/**
	 * 限制输出文件包含的文章数量
	 * @description (0 不限制;> 1 会按照日期排序对输出内容进行调整)
	 */
	limit?: number;
	/**
	 * 生成文件名
	 */
	fileName?: string;
	/**
	 * Feed 配置项
	 */
	feedOptions?: import('feed').FeedOptions;
}
/**
 * RSS 生成
 */
interface RSSConfig {
	/**
	 * 是否启用
	 */
	enable?: boolean;
	/**
	 * 你的站点地址 eg: https://www.imalun.com
	 */
	baseUrl: string;
	/**
	 * 限制输出文件包含的文章数量
	 * @description (0 不限制;> 1 会按照日期排序对输出内容进行调整)
	 */
	limit?: number;
	/**
	 * 生成文件名
	 */
	fileName?: string;
	/**
	 * Feed 配置项
	 */
	feedOptions?: import('feed').FeedOptions;
}

搜索配置

目前仅支持本地搜索,配置与 vitepress 默认主题保持一致,参考 vitepress 配置。

ts
/**
 * 搜索配置
 */
interface SearchConfig {
	provider: 'local';
	options?: import('vitepress').DefaultTheme.LocalSearchOptions;
}
/**
 * 搜索配置
 */
interface SearchConfig {
	provider: 'local';
	options?: import('vitepress').DefaultTheme.LocalSearchOptions;
}

插件配置

主题内置插件配置,默认通过 CDN 方式加载。

ts
export default defineConfig({
	themeConfig: {
		plugin: {
			// 修改默认 CDN 源
			thirdPartyProvider: 'https://npm.elemecdn.com', 
		}
	}
});
export default defineConfig({
	themeConfig: {
		plugin: {
			// 修改默认 CDN 源
			thirdPartyProvider: 'https://npm.elemecdn.com', 
		}
	}
});
ts
/**
 * 插件配置
 */
interface PluginConfig {
	/**
	 * 插件 CDN 源
	 */
	thirdPartyProvider: string;
	/**
	 * 插件列表
	 */
	plugins?: {
		/** 图片预览插件 */
		fancybox?: {
			css?: string;
			js?: string;
		};
		/** 图片排版插件 */
		flickrJustifiedGallery?: string;
	};
}
/**
 * 插件配置
 */
interface PluginConfig {
	/**
	 * 插件 CDN 源
	 */
	thirdPartyProvider: string;
	/**
	 * 插件列表
	 */
	plugins?: {
		/** 图片预览插件 */
		fancybox?: {
			css?: string;
			js?: string;
		};
		/** 图片排版插件 */
		flickrJustifiedGallery?: string;
	};
}

如果不需要使用某个插件,可设置对应插件配置为空,主题则会跳过插件加载

ts
export default defineConfig({
	themeConfig: {
		plugin: {
			flickrJustifiedGallery: null, 
			fancybox: {
				js: null 
			}
		}
	}
});
export default defineConfig({
	themeConfig: {
		plugin: {
			flickrJustifiedGallery: null, 
			fancybox: {
				js: null 
			}
		}
	}
});

内置插槽

插槽位置主要分布在 :

  • 顶部导航栏
    • topbar-left-before
    • topbar-left-after
    • topbar-right-before
    • topbar-right-after
  • 横幅
    • banner-top
    • banner-bottom
  • 侧栏
    • sidebar-before
    • sidebar-user-before
    • sidebar-social-before
    • sidebar-info-before
    • sidebar-email-before
    • sidebar-after
  • 内容区域 ,内容区域除了公用插槽外,文章页、关于页、友链页会存在特有的插槽。
    • page-content-top
    • page-content-bottom
    • 文章页
      • post-before
      • post-info-after
      • post-container-before
      • post-content-before
      • post-content-after
      • post-copyright-before
      • post-reward-before
      • post-reward-after
      • post-pagination-before
      • post-after
    • 关于页
      • about-before
      • about-introduction-before
      • about-blog-before
      • about-privacy-before
      • about-after
    • 友链页
      • links-before
      • links-siteinfo-before
      • links-list-before
      • links-after
  • 固定按钮块
    • fixed-btn-before
    • fixed-btn-after
  • 页尾
    • footer-before
    • footer-content-before
    • footer-content-after
    • footer-after

想看更具体插槽信息 请看这里

全局组件

主题中将页面中部分模块拆分单独的组件,以便于在文章中使用,位于 vitepress-theme-async/components/global 目录中。默认情况下不会注册到全局组件中,需要通过 globalComponents 字段配置是否需要将组件注册为全局组件使用,设置为 true 默认会将所有组件注册为全局组件,也可一传递组件名称 ['TrmDividerTitle'] 选择性的注册。

ts
export default defineConfig({
	themeConfig: {
		globalComponents: true 
	}
});
export default defineConfig({
	themeConfig: {
		globalComponents: true 
	}
});
ts
globalComponents?: boolean | Array<string>;
globalComponents?: boolean | Array<string>;
  • TrmCardCategorie.vue
  • TrmCardLink.vue
  • TrmCardPost.vue
  • TrmCardPostMini.vue
  • TrmDividerTitle.vue
  • TrmGallery.vue
  • TrmPortfolio.vue
  • TrmSwichImgs.vue
  • TrmTimeline.vue
  • 自定义图标

    主题内置图标是通过组件方式使用的,参考 vitepress 覆盖组件使用方式。重写内部组件

    主题内置图标位置 vitepress-theme-async/components/icons

    自定义样式

    参考 vitepress 自定义主题。

    主题内置 css 变量参考 vitepress-theme-async/styles/_variables/index.less 文件

    vitepress-theme-async/styles/_variables/index.less
    less
    .var-primary(@primary: #afb42b; @primary-weak: #c0ca33) {
    	--primary: @primary;
    	--primary-70: fade(@primary, 70%);
    	--primary-50: fade(@primary, 50%);
    	--primary-30: fade(@primary, 30%);
    	--primary-weak: @primary-weak;
    	--primary-weak-50: fade(@primary-weak, 50%);
    }
    
    .var-theme(@body-color: #5d5d5e; @body-bg-color: #00151f; @theme-color: #00283a; @theme-bg-color: #fcfcfe; @theme-bg2-color: #f4f5f7) {
    	--body-color: @body-color;
    	--body-color-30: fade(@body-color, 30%);
    	--body-color-5: fade(@body-color, 5%);
    	--body-bg-color: @body-bg-color;
    	--theme-color: @theme-color;
    	--theme-bg-color: @theme-bg-color;
    	--theme-bg-color-80: fade(@theme-bg-color, 80%);
    	--theme-bg2-color: @theme-bg2-color;
    }
    
    :root {
    	@body-color: #7b7b7d;
    	@theme-bg-color: #fcfcfe;
    
    	// base
    	.var-primary();
    	.var-theme();
    	--top-bar-height: 72px;
    
    	--box-shadow: 0 2px 4px -2px rgba(0, 0, 0, 0.15);
    	--box-shadow2: inset 0 0 4px -1px rgba(0, 0, 0, 0.15);
    	--border-dotted: dotted 2px rgba(225, 225, 235, 0.9);
    
    	// preloader
    	--preloader-background: #00283a;
    
    	// top-bar
    	--top-bar-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.15);
    
    	// card
    	--card-padding: 40px;
    	--card-bottom-card: 40px;
    	--card-border-radius: 10px;
    	--card-top-color: #ffffff;
    	--card-top-bg-color: #ff6a00;
    
    	// cover
    	--card-cover-bg-color: #e9e9e9;
    
    	// table
    	--tabele-thead-bg-color: rgba(153, 169, 191, 0.1);
    	--tabele-thead-border-color: #eee;
    
    	// tabs
    	--tab-border-color: #f1f1f1;
    	--tab-botton-bg-color: #f1f1f1;
    	--tab-botton-color: #7b7b7d;
    	--tab-button-hover-bg-color: #eeeeee;
    	--tab-button-active-bg-color: #ffffff;
    
    	// fixed btn
    	--fixed-button-bg-color: #ffffff;
    	--fixed-button-color: #7b7b7d;
    
    	// code
    	--code-bg-color: #f1f1f1;
    	--code-color: #476582;
    
    	// notice outdate
    	--notice-outdate-bg: #ffe6e6;
    	--notice-outdate-color: #ff6666;
    	--notice-outdate-border: #ff8080;
    
    	// scroll progress
    	--scroll-progress-bg-color: linear-gradient(#ffdddd, #e9ddff);
    
    	// note
    	--note-info-bg-color: #65758529;
    	--note-tip-bg-color: #646cff29;
    	--note-warning-bg-color: #eab30829;
    	--note-danger-bg-color: #f43f5e29;
    	--note-details-bg-color: #eaeaea;
    
    	// ::selection
    	--selection-bg-color: #1f2d3d;
    	--selection-color: #f1f1f1;
    
    	// Code
    	--code-line-height: 1.7;
    	--code-font-size: 0.875em;
    	--code-color: #3451b2;
    	--code-link-color: #3451b2;
    	--code-link-hover-color: #3a5ccc;
    	--code-bg: rgba(142, 150, 170, 0.14);
    
    	--code-block-color: rgba(60, 60, 67, 0.78);
    	--code-block-bg: #f6f6f7;
    	--code-block-divider-color: #e2e2e3;
    
    	--code-lang-color: rgba(60, 60, 67, 0.56);
    
    	--code-line-highlight-color: rgba(142, 150, 170, 0.14);
    	--code-line-number-color: rgba(60, 60, 67, 0.56);
    
    	--code-line-diff-add-color: rgba(16, 185, 129, 0.14);
    	--code-line-diff-add-symbol-color: #18794e;
    
    	--code-line-diff-remove-color: rgba(244, 63, 94, 0.14);
    	--code-line-diff-remove-symbol-color: #b8272c;
    
    	--code-line-warning-color: rgba(234, 179, 8, 0.14);
    	--code-line-error-color: rgba(244, 63, 94, 0.14);
    
    	--code-copy-code-border-color: #e2e2e3;
    	--code-copy-code-bg: #f6f6f7;
    	--code-copy-code-hover-border-color: #e2e2e3;
    	--code-copy-code-hover-bg: #ffffff;
    	--code-copy-code-active-text: rgba(60, 60, 67, 0.78);
    	--code-copy-copied-text-content: "Copied";
    
    	--code-tab-divider: #e2e2e3;
    	--code-tab-text-color: rgba(60, 60, 67, 0.78);
    	--code-tab-bg: #f6f6f7;
    	--code-tab-hover-text-color: rgba(60, 60, 67);
    	--code-tab-active-text-color: rgba(60, 60, 67);
    	--code-tab-active-bar-color: #3451b2;
    
    	--code-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2'/%3E%3C/svg%3E");
    	--code-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m-6 9 2 2 4-4'/%3E%3C/svg%3E");
    }
    
    .dark() {
    	// base
    	.var-primary();
    	.var-theme(#d1d9e9b3, #00151f, #dedee0, #00283a, #02162b);
    
    	--box-shadow: 0 2px 4px -2px rgba(0, 0, 0, 0.6);
    	--box-shadow2: inset 0 0 4px -1px rgba(0, 0, 0, 0.6);
    	--border-dotted: dotted 2px rgba(225, 225, 235, 0.15);
    
    	// preloader
    	--preloader-background: #dedee0;
    
    	// top-bar
    	--top-bar-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.6);
    
    	// cover
    	--card-cover-bg-color: #162e38;
    
    	// table
    	--tabele-thead-bg-color: #525f663d;
    	--tabele-thead-border-color: #ffffff1c;
    
    	// tabs
    	--tab-border-color: #063c54;
    	--tab-botton-bg-color: #063c54;
    	--tab-botton-color: #dedee0;
    	--tab-button-hover-bg-color: #003146;
    	--tab-button-active-bg-color: #042838;
    
    	// fixed btn
    	--fixed-button-bg-color: #063c54;
    	--fixed-button-color: #dedee0;
    
    	// code
    	--code-bg-color: #3a3a3a;
    	--code-color: #c9def1;
    
    	// notice outdate
    	--notice-outdate-bg: #403131;
    	--notice-outdate-color: #ff6565;
    	--notice-outdate-border: #bb1e1e;
    
    	// scroll progress
    	--scroll-progress-bg-color: linear-gradient(#82df7a80, #82df7a80);
    
    	// note
    	--note-details-bg-color: #272a2f;
    
    	// ::selection
    	--selection-bg-color: #f1f1f1;
    	--selection-color: #1f2d3d;
    
    	// code
    	--code-color: #a8b1ff;
    	--code-link-color: #a8b1ff;
    	--code-link-hover-color: #5c73e7;
    	--code-bg: rgba(101, 117, 133, 0.16);
    
    	--code-block-color: rgba(235, 235, 245, 0.6);
    	--code-block-bg: #161618;
    	--code-block-divider-color: #000000;
    
    	--code-lang-color: rgba(235, 235, 245, 0.38);
    
    	--code-line-highlight-color: rgba(101, 117, 133, 0.16);
    	--code-line-number-color: rgba(235, 235, 245, 0.38);
    
    	--code-line-diff-add-color: rgba(16, 185, 129, 0.16);
    	--code-line-diff-add-symbol-color: #3dd68c;
    
    	--code-line-diff-remove-color: rgba(244, 63, 94, 0.16);
    	--code-line-diff-remove-symbol-color: #f66f81;
    
    	--code-line-warning-color: rgba(234, 179, 8, 0.16);
    	--code-line-error-color: rgba(244, 63, 94, 0.16);
    
    	--code-copy-code-border-color: #2e2e32;
    	--code-copy-code-bg: #202127;
    	--code-copy-code-hover-border-color: #2e2e32;
    	--code-copy-code-hover-bg: #1b1b1f;
    	--code-copy-code-active-text: rgba(235, 235, 245, 0.6);
    	--code-copy-copied-text-content: "Copied";
    
    	--code-tab-divider: #000000;
    	--code-tab-text-color: rgba(235, 235, 245, 0.6);
    	--code-tab-bg: #161618;
    	--code-tab-hover-text-color: rgba(255, 255, 245, 0.86);
    	--code-tab-active-text-color: rgba(255, 255, 245, 0.86);
    	--code-tab-active-bar-color: #a8b1ff;
    }
    
    :root.dark {
    	.dark();
    }
    
    @media (max-width: 768px) {
    	:root {
    		--card-padding: 20px;
    		--card-bottom-card: 10px;
    		--card-border-radius: 6px;
    
    		blockquote:before {
    			top: 0;
    		}
    	}
    }
    
    // transition mixin
    .transition-mixin(@type: all; @time: 0.4s) {
    	transition: @type @time ease-in-out;
    }
    
    //
    .ellipsis() {
    	overflow: hidden;
    	white-space: nowrap;
    	text-overflow: ellipsis;
    }
    
    //
    .line-ellipsis(@line: 2) {
    	overflow: hidden;
    	text-overflow: ellipsis;
    	display: -webkit-box;
    	-webkit-box-orient: vertical;
    	-webkit-line-clamp: @line;
    }
    
    .dark .vp-code-light {
    	display: none;
    }
    
    html:not(.dark) .vp-code-dark {
    	display: none;
    }
    
    .shadow {
    	transition:
    		all 0.4s ease-in-out,
    		box-shadow 0.3s ease;
    	box-shadow: var(--box-shadow);
    
    	&:hover {
    		box-shadow: var(--box-shadow-hover);
    	}
    }
    .var-primary(@primary: #afb42b; @primary-weak: #c0ca33) {
    	--primary: @primary;
    	--primary-70: fade(@primary, 70%);
    	--primary-50: fade(@primary, 50%);
    	--primary-30: fade(@primary, 30%);
    	--primary-weak: @primary-weak;
    	--primary-weak-50: fade(@primary-weak, 50%);
    }
    
    .var-theme(@body-color: #5d5d5e; @body-bg-color: #00151f; @theme-color: #00283a; @theme-bg-color: #fcfcfe; @theme-bg2-color: #f4f5f7) {
    	--body-color: @body-color;
    	--body-color-30: fade(@body-color, 30%);
    	--body-color-5: fade(@body-color, 5%);
    	--body-bg-color: @body-bg-color;
    	--theme-color: @theme-color;
    	--theme-bg-color: @theme-bg-color;
    	--theme-bg-color-80: fade(@theme-bg-color, 80%);
    	--theme-bg2-color: @theme-bg2-color;
    }
    
    :root {
    	@body-color: #7b7b7d;
    	@theme-bg-color: #fcfcfe;
    
    	// base
    	.var-primary();
    	.var-theme();
    	--top-bar-height: 72px;
    
    	--box-shadow: 0 2px 4px -2px rgba(0, 0, 0, 0.15);
    	--box-shadow2: inset 0 0 4px -1px rgba(0, 0, 0, 0.15);
    	--border-dotted: dotted 2px rgba(225, 225, 235, 0.9);
    
    	// preloader
    	--preloader-background: #00283a;
    
    	// top-bar
    	--top-bar-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.15);
    
    	// card
    	--card-padding: 40px;
    	--card-bottom-card: 40px;
    	--card-border-radius: 10px;
    	--card-top-color: #ffffff;
    	--card-top-bg-color: #ff6a00;
    
    	// cover
    	--card-cover-bg-color: #e9e9e9;
    
    	// table
    	--tabele-thead-bg-color: rgba(153, 169, 191, 0.1);
    	--tabele-thead-border-color: #eee;
    
    	// tabs
    	--tab-border-color: #f1f1f1;
    	--tab-botton-bg-color: #f1f1f1;
    	--tab-botton-color: #7b7b7d;
    	--tab-button-hover-bg-color: #eeeeee;
    	--tab-button-active-bg-color: #ffffff;
    
    	// fixed btn
    	--fixed-button-bg-color: #ffffff;
    	--fixed-button-color: #7b7b7d;
    
    	// code
    	--code-bg-color: #f1f1f1;
    	--code-color: #476582;
    
    	// notice outdate
    	--notice-outdate-bg: #ffe6e6;
    	--notice-outdate-color: #ff6666;
    	--notice-outdate-border: #ff8080;
    
    	// scroll progress
    	--scroll-progress-bg-color: linear-gradient(#ffdddd, #e9ddff);
    
    	// note
    	--note-info-bg-color: #65758529;
    	--note-tip-bg-color: #646cff29;
    	--note-warning-bg-color: #eab30829;
    	--note-danger-bg-color: #f43f5e29;
    	--note-details-bg-color: #eaeaea;
    
    	// ::selection
    	--selection-bg-color: #1f2d3d;
    	--selection-color: #f1f1f1;
    
    	// Code
    	--code-line-height: 1.7;
    	--code-font-size: 0.875em;
    	--code-color: #3451b2;
    	--code-link-color: #3451b2;
    	--code-link-hover-color: #3a5ccc;
    	--code-bg: rgba(142, 150, 170, 0.14);
    
    	--code-block-color: rgba(60, 60, 67, 0.78);
    	--code-block-bg: #f6f6f7;
    	--code-block-divider-color: #e2e2e3;
    
    	--code-lang-color: rgba(60, 60, 67, 0.56);
    
    	--code-line-highlight-color: rgba(142, 150, 170, 0.14);
    	--code-line-number-color: rgba(60, 60, 67, 0.56);
    
    	--code-line-diff-add-color: rgba(16, 185, 129, 0.14);
    	--code-line-diff-add-symbol-color: #18794e;
    
    	--code-line-diff-remove-color: rgba(244, 63, 94, 0.14);
    	--code-line-diff-remove-symbol-color: #b8272c;
    
    	--code-line-warning-color: rgba(234, 179, 8, 0.14);
    	--code-line-error-color: rgba(244, 63, 94, 0.14);
    
    	--code-copy-code-border-color: #e2e2e3;
    	--code-copy-code-bg: #f6f6f7;
    	--code-copy-code-hover-border-color: #e2e2e3;
    	--code-copy-code-hover-bg: #ffffff;
    	--code-copy-code-active-text: rgba(60, 60, 67, 0.78);
    	--code-copy-copied-text-content: "Copied";
    
    	--code-tab-divider: #e2e2e3;
    	--code-tab-text-color: rgba(60, 60, 67, 0.78);
    	--code-tab-bg: #f6f6f7;
    	--code-tab-hover-text-color: rgba(60, 60, 67);
    	--code-tab-active-text-color: rgba(60, 60, 67);
    	--code-tab-active-bar-color: #3451b2;
    
    	--code-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2'/%3E%3C/svg%3E");
    	--code-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m-6 9 2 2 4-4'/%3E%3C/svg%3E");
    }
    
    .dark() {
    	// base
    	.var-primary();
    	.var-theme(#d1d9e9b3, #00151f, #dedee0, #00283a, #02162b);
    
    	--box-shadow: 0 2px 4px -2px rgba(0, 0, 0, 0.6);
    	--box-shadow2: inset 0 0 4px -1px rgba(0, 0, 0, 0.6);
    	--border-dotted: dotted 2px rgba(225, 225, 235, 0.15);
    
    	// preloader
    	--preloader-background: #dedee0;
    
    	// top-bar
    	--top-bar-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.6);
    
    	// cover
    	--card-cover-bg-color: #162e38;
    
    	// table
    	--tabele-thead-bg-color: #525f663d;
    	--tabele-thead-border-color: #ffffff1c;
    
    	// tabs
    	--tab-border-color: #063c54;
    	--tab-botton-bg-color: #063c54;
    	--tab-botton-color: #dedee0;
    	--tab-button-hover-bg-color: #003146;
    	--tab-button-active-bg-color: #042838;
    
    	// fixed btn
    	--fixed-button-bg-color: #063c54;
    	--fixed-button-color: #dedee0;
    
    	// code
    	--code-bg-color: #3a3a3a;
    	--code-color: #c9def1;
    
    	// notice outdate
    	--notice-outdate-bg: #403131;
    	--notice-outdate-color: #ff6565;
    	--notice-outdate-border: #bb1e1e;
    
    	// scroll progress
    	--scroll-progress-bg-color: linear-gradient(#82df7a80, #82df7a80);
    
    	// note
    	--note-details-bg-color: #272a2f;
    
    	// ::selection
    	--selection-bg-color: #f1f1f1;
    	--selection-color: #1f2d3d;
    
    	// code
    	--code-color: #a8b1ff;
    	--code-link-color: #a8b1ff;
    	--code-link-hover-color: #5c73e7;
    	--code-bg: rgba(101, 117, 133, 0.16);
    
    	--code-block-color: rgba(235, 235, 245, 0.6);
    	--code-block-bg: #161618;
    	--code-block-divider-color: #000000;
    
    	--code-lang-color: rgba(235, 235, 245, 0.38);
    
    	--code-line-highlight-color: rgba(101, 117, 133, 0.16);
    	--code-line-number-color: rgba(235, 235, 245, 0.38);
    
    	--code-line-diff-add-color: rgba(16, 185, 129, 0.16);
    	--code-line-diff-add-symbol-color: #3dd68c;
    
    	--code-line-diff-remove-color: rgba(244, 63, 94, 0.16);
    	--code-line-diff-remove-symbol-color: #f66f81;
    
    	--code-line-warning-color: rgba(234, 179, 8, 0.16);
    	--code-line-error-color: rgba(244, 63, 94, 0.16);
    
    	--code-copy-code-border-color: #2e2e32;
    	--code-copy-code-bg: #202127;
    	--code-copy-code-hover-border-color: #2e2e32;
    	--code-copy-code-hover-bg: #1b1b1f;
    	--code-copy-code-active-text: rgba(235, 235, 245, 0.6);
    	--code-copy-copied-text-content: "Copied";
    
    	--code-tab-divider: #000000;
    	--code-tab-text-color: rgba(235, 235, 245, 0.6);
    	--code-tab-bg: #161618;
    	--code-tab-hover-text-color: rgba(255, 255, 245, 0.86);
    	--code-tab-active-text-color: rgba(255, 255, 245, 0.86);
    	--code-tab-active-bar-color: #a8b1ff;
    }
    
    :root.dark {
    	.dark();
    }
    
    @media (max-width: 768px) {
    	:root {
    		--card-padding: 20px;
    		--card-bottom-card: 10px;
    		--card-border-radius: 6px;
    
    		blockquote:before {
    			top: 0;
    		}
    	}
    }
    
    // transition mixin
    .transition-mixin(@type: all; @time: 0.4s) {
    	transition: @type @time ease-in-out;
    }
    
    //
    .ellipsis() {
    	overflow: hidden;
    	white-space: nowrap;
    	text-overflow: ellipsis;
    }
    
    //
    .line-ellipsis(@line: 2) {
    	overflow: hidden;
    	text-overflow: ellipsis;
    	display: -webkit-box;
    	-webkit-box-orient: vertical;
    	-webkit-line-clamp: @line;
    }
    
    .dark .vp-code-light {
    	display: none;
    }
    
    html:not(.dark) .vp-code-dark {
    	display: none;
    }
    
    .shadow {
    	transition:
    		all 0.4s ease-in-out,
    		box-shadow 0.3s ease;
    	box-shadow: var(--box-shadow);
    
    	&:hover {
    		box-shadow: var(--box-shadow-hover);
    	}
    }

    自定义组件

    参考 vitepress 覆盖组件使用方式。 重写内部组件

    Released under the SATA | MIT License.