When rendering index pages, it can be convenient to import multiple pages or MDX documents.
Although using import.meta.globEager works well, provides a better option.
useDocumentsThe 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
frontmatterare instantly reflected.It does not require a full page reload when files matching the pattern are added or removed.
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 // PageFrontmatterSince 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.globEagerimport.meta.globEager, as it serves a single file