How do I write an async request to get a markdown file's content? Svelte

Viewed 238

I'm having a great time building my blog with Svelte, but I'm switching the structure to to be accessed through a JSON API.

Right now it's easy to get the markdown metadata and path, but I'd love to also get the content.

How would I modify this posts.json.js file to also get the content?

  const allPostFiles = import.meta.glob('../blog/posts/*.md')
  const iterablePostFiles = Object.entries(allPostFiles)

  const allPosts = await Promise.all(
    iterablePostFiles.map(async ([path, resolver]) => {
      const { metadata } = await resolver()
      const postPath = path.slice(2, -3)

      return {
        meta: metadata,
        path: postPath
      }
    })
  )

  const sortedPosts = allPosts.sort((a, b) => {
    return new Date(b.meta.date) - new Date(a.meta.date)
  })

  return {
    body: sortedPosts
  }
2 Answers

Install and enable the vite-plugin-markdown

// svelte.config.js
import { plugin as markdown, Mode } from "vite-plugin-markdown";

/** @type {import('@sveltejs/kit').Config} */
export default {
  kit: {
    vite: {
      plugins: [markdown({ mode: Mode.HTML })],
    },
  },
};

then the content will be available as html and frontmatter data as attributes

    iterablePostFiles.map(async ([path, resolver]) => {
      const { attributes, html } = await resolver();

      return {
        attributes,
        html,
        path: path.slice(2, -3),
      };
    })

(I suggest adding the metadata into the markdown files via frontmatter )

The answer above works perfectly, but it also works to tweak the API with this code:


  const allPosts = await Promise.all(
    iterablePostFiles.map(async ([path, resolver]) => {
      const { metadata } = await resolver()
      // because we know every path will start with '..' and end with '.md', we can slice from the beginning and the end
      const postPath = path.slice(2, -3)

      const post = await resolver()
      const content = post.default.render()

      return {
        meta: metadata,
        path: postPath,
        text: content
      }
    })
  )

The important addition is this:

      const post = await resolver()
      const content = post.default.render()

using these variable chains to avoid using the JS reserved word default.

Related