963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
4.3 KiB
4.3 KiB
name, description
| name | description |
|---|---|
| vitepress-data-loading | Build-time data loaders for fetching remote data or processing local files |
Data Loading
VitePress data loaders run at build time to load arbitrary data that's serialized as JSON in the client bundle.
Basic Usage
Create a file ending with .data.js or .data.ts:
// example.data.ts
export default {
load() {
return {
hello: 'world',
timestamp: Date.now(),
};
},
};
Import the data named export:
<script setup>
import { data } from './example.data.ts';
</script>
<template>
<pre>{{ data }}</pre>
</template>
Async Data
Fetch remote data:
// api.data.ts
export default {
async load() {
const response = await fetch('https://api.example.com/data');
return response.json();
},
};
Local Files with Watch
Process local files with hot reload:
// posts.data.ts
import fs from 'node:fs';
import { parse } from 'csv-parse/sync';
export default {
watch: ['./data/*.csv'],
load(watchedFiles) {
// watchedFiles = array of absolute paths
return watchedFiles.map((file) => {
return parse(fs.readFileSync(file, 'utf-8'), {
columns: true,
skip_empty_lines: true,
});
});
},
};
createContentLoader
Helper for loading markdown content (common for blogs/archives):
// posts.data.ts
import { createContentLoader } from 'vitepress';
export default createContentLoader('posts/*.md');
Returns array of ContentData:
interface ContentData {
url: string; // e.g. /posts/hello.html
frontmatter: Record<string, any>;
src?: string; // raw markdown (opt-in)
html?: string; // rendered HTML (opt-in)
excerpt?: string; // excerpt HTML (opt-in)
}
With options:
// posts.data.ts
import { createContentLoader } from 'vitepress';
export default createContentLoader('posts/*.md', {
includeSrc: true, // Include raw markdown
render: true, // Include rendered HTML
excerpt: true, // Include excerpt (content before first ---)
transform(rawData) {
// Sort by date, newest first
return rawData
.sort((a, b) => +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date))
.map((page) => ({
title: page.frontmatter.title,
url: page.url,
date: page.frontmatter.date,
excerpt: page.excerpt,
}));
},
});
Usage Example: Blog Index
// posts.data.ts
import { createContentLoader } from 'vitepress';
export default createContentLoader('posts/*.md', {
excerpt: true,
transform(data) {
return data
.filter((post) => !post.frontmatter.draft)
.sort((a, b) => +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date));
},
});
<!-- posts/index.md -->
<script setup>
import { data as posts } from './posts.data.ts';
</script>
<template>
<ul>
<li v-for="post in posts" :key="post.url">
<a :href="post.url">{{ post.frontmatter.title }}</a>
<span>{{ post.frontmatter.date }}</span>
</li>
</ul>
</template>
Typed Data Loaders
// example.data.ts
import { defineLoader } from 'vitepress';
export interface Data {
posts: Array<{ title: string; url: string }>;
}
declare const data: Data;
export { data };
export default defineLoader({
watch: ['./posts/*.md'],
async load(): Promise<Data> {
// ...
return { posts: [] };
},
});
In Build Hooks
Use in config for generating additional files:
// .vitepress/config.ts
import { createContentLoader } from 'vitepress';
export default {
async buildEnd() {
const posts = await createContentLoader('posts/*.md').load();
// Generate RSS feed, sitemap, etc.
},
};
Accessing Config
// example.data.ts
import type { SiteConfig } from 'vitepress';
export default {
load() {
const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG;
return { base: config.site.base };
},
};
Key Points
- Data loaders run only at build time in Node.js
- File must end with
.data.jsor.data.ts - Import the
datanamed export (not default) - Use
watchfor local file hot reload during dev createContentLoadersimplifies loading markdown collections- Keep data small - it's inlined in the client bundle
- Heavy data should use
transformto reduce payload