Development toolkit for VitePress plugin authors, providing shared utilities, components, and composables for both Node and Client side.
pnpm add vitepress-plugin-toolkit| Entry | Description |
|---|---|
vitepress-plugin-toolkit |
Node-side tools (markdown-it plugins, Vite plugins, VitePress config utilities) |
vitepress-plugin-toolkit/client |
Client-side tools (Vue components, composables, environment detection) |
vitepress-plugin-toolkit/styles/* |
CSS transition animations and component styles |
Creates an embed rule block for parsing @[type info](source) syntax in markdown.
import { createEmbedRuleBlock } from 'vitepress-plugin-toolkit'
createEmbedRuleBlock(md, {
type: 'video',
meta: (info, source) => ({ src: source, title: info }),
content: meta => `<video src="${meta.src}" title="${meta.title}"></video>`,
})Usage in markdown:
@[video My Video](https://example.com/video.mp4)Options:
| Parameter | Type | Description |
|---|---|---|
type |
string |
Embed type identifier, e.g. 'video', 'embed' |
name |
string |
Optional, custom token name, defaults to embed_${type} |
meta |
(info: string, source: string) => Meta |
Parses info and source into a metadata object |
content |
(meta: Meta, env: MarkdownEnv) => string |
Optional, generates HTML content from metadata |
Creates a custom container plugin based on markdown-it-container. Content is processed normally by markdown-it.
import { createContainerPlugin } from 'vitepress-plugin-toolkit'
md.use(createContainerPlugin, 'tip', {
before: info => `<div class="tip">${info}`,
after: () => '</div>',
})Usage in markdown:
::: tip Note
This is a tip message
:::Options:
| Parameter | Type | Description |
|---|---|---|
before |
(info: string, ...args: RenderRuleParams) => string |
Optional, callback for container opening tag |
after |
(info: string, ...args: RenderRuleParams) => string |
Optional, callback for container closing tag |
Creates a custom container syntax plugin. Content inside the container is NOT processed by markdown-it, but passed entirely to a custom render function.
import { createContainerSyntaxPlugin } from 'vitepress-plugin-toolkit'
createContainerSyntaxPlugin(md, 'chart', (tokens, idx) => {
const { content, meta } = tokens[idx]
return `<div class="chart">${content}</div>`
})Retrieves the current VitePress site configuration from globalThis.VITEPRESS_CONFIG.
import { getVitepressConfig } from 'vitepress-plugin-toolkit'
const config = getVitepressConfig()
console.log(config.userConfig.title)Creates a locales configuration by merging built-in locale data with user-provided locale data.
import { createLocales } from 'vitepress-plugin-toolkit'
const locales = createLocales(
[
[['en', 'en-US'], { title: 'English' }],
[['zh', 'zh-CN'], { title: '中文' }],
],
{ zh: { title: 'My Site' } },
)Resolves markdown links according to VitePress routing rules:
- External links returned as-is
- Absolute paths prefixed with site base
- Relative
.mdlinks converted to.htmlbased oncleanUrls index.mdcollapsed to directory path- Hash fragments auto-slugified
import { resolveRouteLink } from 'vitepress-plugin-toolkit'
resolveRouteLink('./guide.md', env) // -> './guide.html' (depends on cleanUrls)Returns the language code and locale prefix for a given path.
import { getLocaleWithPath } from 'vitepress-plugin-toolkit'
getLocaleWithPath('/zh/guide/') // { lang: 'zh-CN', locale: '/zh/' }
getLocaleWithPath('/guide/') // { lang: 'en', locale: '' } (root)Creates a Vite plugin that registers SVG icons as CSS custom properties (--icon), generating CSS selectors like .vpi-<name>.
import { iconPlugin } from 'vitepress-plugin-toolkit'
defineConfig({
vite: {
plugins: [
iconPlugin([
{ name: 'github', svg: '<svg>...</svg>' },
{ name: 'twitter', svg: '<svg>...</svg>' },
]),
],
},
})Display icons by adding class names:
<span class="vpi-github"></span>Parses an attribute string into an object, or extracts a single attribute value.
Supports key="value" format and boolean attributes (disabled, etc.).
import { resolveAttrs, resolveAttr } from 'vitepress-plugin-toolkit'
resolveAttrs('width="100" height="50"') // { width: '100', height: '50' }
resolveAttr('width="100" height="50"', 'width') // '100'Stringifies an attributes object into an HTML attribute string. Automatically handles Boolean, Number, and String types.
import { stringifyAttrs } from 'vitepress-plugin-toolkit'
stringifyAttrs({ width: 100, disabled: true })
// ' :width="100" disabled'Parses a size string, appending a unit (default px) to bare numbers.
import { parseRect } from 'vitepress-plugin-toolkit'
parseRect('100') // '100px'
parseRect('50%') // '50%'
parseRect('200', 'rpx') // '200rpx'Generates a URL-friendly slug, removing accents, control characters, and special characters, and merging consecutive separators.
import { slugify } from 'vitepress-plugin-toolkit'
slugify('Hello World!') // 'hello-world'Generates a SHA-256 hash for any data, with optional truncation length.
import { genHash } from 'vitepress-plugin-toolkit'
genHash('hello') // full SHA-256 hash
genHash({ a: 1 }, 8) // 8-character hashDetermines whether a file should be treated as an HTML route (not a static asset).
import { treatAsHtml } from 'vitepress-plugin-toolkit'
treatAsHtml('about') // true
treatAsHtml('logo.png') // falseCreates a formatted logger instance with colored labels and timestamps.
import { createLogger } from 'vitepress-plugin-toolkit'
const logger = createLogger('my-plugin', 'info')
logger.info('Build started')
logger.warn('Deprecated feature used')
logger.debug('Verbose details', 'debug')import {
isBuild, // Whether building for production
isDev, // Whether in development mode
EXTENSION_VIDEOS, // Browser-supported video file extensions
EXTENSION_IMAGES, // Browser-supported image file extensions
EXTENSION_AUDIOS, // Browser-supported audio file extensions
} from 'vitepress-plugin-toolkit'VPCopyButton— Copy-to-clipboard button componentVPLoading— Loading animation componentVPTabSwitch— Tab switch component
<script setup>
import { VPCopyButton, VPLoading, VPTabSwitch } from 'vitepress-plugin-toolkit/client'
</script>
<template>
<VPCopyButton text="Click to copy this text" />
<VPLoading :size="40" />
<VPTabSwitch :tabs="['Code', 'Preview']" />
</template>Reactive size calculation based on width, height, and aspect ratio options. Automatically listens for window resize and orientationchange events.
import { useSize } from 'vitepress-plugin-toolkit/client'
const el = ref<HTMLElement>()
const { width, height, resize } = useSize(
el,
toRefs({ width: '100%', ratio: '16:9' }),
)Provides zoom and drag interaction for a content stage, supporting mouse drag, touch drag, and pinch-to-zoom.
import { useZoomAndDrag } from 'vitepress-plugin-toolkit/client'
const stageEl = ref<HTMLDivElement>()
const { actorStyle, zoom, zoomIn, zoomOut, resetZoom, reset } = useZoomAndDrag(stageEl)import {
isiPhone, // Is iPhone
isiPad, // Is iPad
isIOS, // Is iOS
isWindows, // Is Windows
isMacOS, // Is macOS
isSafari, // Is Safari browser
isMobile, // Is mobile device
} from 'vitepress-plugin-toolkit/client'Import preset CSS transition classes via vitepress-plugin-toolkit/styles/*:
vitepress-plugin-toolkit/styles/transition/fade-in.css
vitepress-plugin-toolkit/styles/transition/fade-in-up.css
vitepress-plugin-toolkit/styles/transition/fade-in-down.css
vitepress-plugin-toolkit/styles/transition/fade-in-left.css
vitepress-plugin-toolkit/styles/transition/fade-in-right.css
vitepress-plugin-toolkit/styles/transition/fade-in-scale-up.css
vitepress-plugin-toolkit/styles/transition/fade-in-width-expand.css
vitepress-plugin-toolkit/styles/transition/fade-in-height-expand.css
vitepress-plugin-toolkit/styles/transition/slide-in-up.css
vitepress-plugin-toolkit/styles/transition/slide-in-down.css
vitepress-plugin-toolkit/styles/transition/slide-in-left.css
vitepress-plugin-toolkit/styles/transition/slide-in-right.css
import 'vitepress-plugin-toolkit/styles/transition/fade-in-up.css'The following utilities are available on both Node and Client side.
Checks whether a path is an external URL.
import { isExternal, isLinkWithProtocol } from 'vitepress-plugin-toolkit'
isExternal('https://example.com') // true
isExternal('/about') // false
isLinkWithProtocol('//cdn.example.com/lib.js') // trueRegular expressions for matching external URLs and protocol schemes.
TypeScript interface for size configuration:
interface SizeOptions {
width?: string // Width CSS value, e.g. '100%', '640px'
height?: string // Height CSS value, e.g. 'auto', '360px'
ratio?: number | string // Aspect ratio, e.g. 16/9 or '16:9'
}MIT