When rendering index pages, it can be convenient to import multiple pages or MDX documents.
Although using import.meta.glob('./dir/*.mdx', { eager: true })
works well, provides a better option.
useDocuments
The useDocuments composable can be used to access all files that are under the specified directory, or match a given pattern.
useDocuments('~/pages/posts')
Provide a glob pattern if you need to narrow down the matched documents:
useDocuments('~/pages/(posts|articles)/*.{md,mdx}')
Great HMR Support 🚀Changes to each document and its
frontmatter
are instantly reflected.It does not require a full page reload when files matching the pattern are added or removed.
Only String LiteralsJust like glob imports in Vite.js, you need to provide a string pattern directly, variables are not supported as it wouldn't be possible to perform static analysis and infer which files to build.
You can access each file's frontmatter
and meta
directly:
<script setup lang="ts">
const posts = useDocuments('~/pages/posts')
</script>
<template>
<h1>Posts</h1>
<article v-for="post of posts">
<time :datetime="post.date.toISOString()">{{ formatDate(post.date) }}</time>
<h2>
<a :href="post.href">{{ post.title }}</a>
</h2>
<component :is="post" excerpt/>
</article>
</template>
Rendering each documentYou can render each document by passing it directly to
<component>
.
Any frontmatter
and meta
properties will be typed, including extensions you have declared for PageMeta
or PageFrontmatter
.
function usePosts () {
return useDocuments<Post>('~/pages/posts')
}
// typeof usePosts === ComputedRef<Post[]>
post.href // string
post.meta // PageMeta
post.frontmatter // PageFrontmatter
Since useDocuments returns a Ref
, when accessing documents in a script you would do:
export function usePosts () {
const posts = useDocuments('~/pages/posts')
return computed(() => posts.value.sort(byDate))
}
If you want to avoid using value
, you can use ref sugar by wrapping it with $()
:
export function usePosts () {
const posts = $(useDocuments('~/pages/posts'))
return computed(() => posts.sort(byDate))
}
import.meta.glob
import.meta.glob('./dir/*.mdx', { eager: true })
, as it serves a single file