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.
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.
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.globEager
import.meta.globEager
, as it serves a single file