vitepress icon indicating copy to clipboard operation
vitepress copied to clipboard

Generate dynamic routes after performing build-time data loading

Open bsdayo opened this issue 1 year ago • 5 comments

Is your feature request related to a problem? Please describe.

I am working on a blog based on VitePress. In my current situation, I need to extract tags from all my posts to generate pages similar to tags/xxx/.

My directory structure:

blog
  |- .vitepress
  |- posts
  |   |- example-post-1
  |       |- index.md
  |   |- example-post-2
  |       |- index.md
  |- tags
  |   |- [tag].md
  |   |- [tag].paths.ts
  |- posts.data.ts

Example post 1:

---
title: Example Post 1
tags:
  - tag1
  - tag2
---

Example post 2:

---
title: Example Post 2
tags:
  - tag2
  - tag3
---

I wrote a posts.data.ts as a build-time data loader to load all these posts:

import { createContentLoader } from 'vitepress'
import { getPostFromContentData } from "./utils"  // some internal processing

const loader = createContentLoader('posts/**/index.md')
export default {
  ...loader,
  async load() {
    const data = await loader.load()
    return data.map(getPostFromContentData)
  }
}

My aim is to generate some pages like tags/tag1/, tags/tag2/ and tags/tag3/, so I created a [tag].paths.ts.

I want to directly access the loader in it:

import { data as posts } from '../posts.data'

export default {
  paths() {
    const tags = new Set<string>()
    for (const post of posts)
      for (const tag of post.tags)
        tags.add(tag)
    return Array.from(tags)
  }
}

That seems impossible, and throws a error while building:

No matching export in "posts.data.ts" for import "data"

I guess the route generation is performed before the build-time data loading, so the loader is not available when generating routes. Could it be solved?

p.s. My English is REALLY bad :( and I hope you can understand my thoughts. Thanks!

Describe the solution you'd like

Maybe we can load data first? Then we could use the loader in other build-time components later.

Describe alternatives you've considered

No response

Additional context

No response

Validations

bsdayo avatar Aug 21 '23 15:08 bsdayo

Very nice idea! Can open many new possibilities for building versatile page structures.

davay42 avatar Aug 22 '23 16:08 davay42

I have some problem as you. when i start project with createContentLoader in config.mjs will be failed to start server, i delete createContentLoader the project can start.

I use node.js can fix it, but will lost frontmatter information .

zhengxinonly avatar Aug 29 '23 19:08 zhengxinonly

Same here.

ryancui92 avatar Mar 09 '24 15:03 ryancui92