sdorra / content-collections

Transform your content into type-safe data collections
https://content-collections.dev
MIT License
415 stars 18 forks source link

Is MDX supported in SvelteKit? #251

Open tsriram opened 3 weeks ago

tsriram commented 3 weeks ago

Hello there! First of all, thanks much for this great library. I've been using it in a Next.js project with MDX and it's been great.

I just started with a SvelteKit project and I couldn't get it the MDX content rendered correctly. Based on my understanding from the docs, MDXContent component is available only for React. I tried using @html directive from Svelte to render MDX content but it's not working. I also see that the SvelteKit sample only has Markdown example. Can someone please let me know if MDX is fully supported in SvelteKit? Or should I use this along with a library like MDsvEX? Thanks!

sdorra commented 3 weeks ago

Hi @tsriram, MDX works only with react. MDsveX is the way to go for svelte. It should be possible to use compile of MDsveX within the transform function of content-collections.

And if you want to go an extra mile, i would happily accept a pr with @content-collections/mdsvex 😁

tsriram commented 3 weeks ago

Got it, thanks @sdorra. Sure, I'd love to contribute. Will get to this in the coming week.

Just to make sure my understanding is correct, @content-collections/mdsvex would be the Svelte equivalent of @content-collections/mdx right?

sdorra commented 3 weeks ago

Yes, the package should call the compile function of mdsvex and cache the results. You can look at how the MDX and Markdown packages are implemented for inspiration.

theetrain commented 3 weeks ago

I recently started using content-collections with mdsvex. This is what a /src/routes/blog/[slug]/+page.js looks like on my site:

import { allPosts } from 'content-collections'
import { error } from '@sveltejs/kit'

/** @type {import('./$types').PageLoad} */
export async function load({ params }) {
  const post = allPosts.find((el) => el.slug === params.slug)

  // 🔽 import is handled by mdsvex preprocessor
  const Post = (await import(`$blog/${post._meta.path}.svx`)).default

  if (!post) error(404, 'Post not found.')

  return {
    Post,
    title: post.title,
    slug: post.slug
  }
}

Since this leverages the mdsvex Vite plugin, it allows imports in .svx files such as:

/src/blog/hello-world.svx

---
title: Hello world
---

<script>
  import Thing from '$blog/Thing.svelte'
</script>

<Thing />

Some test markdown.

I think things become limiting when using the compile function supplied from mdsvex, which can translate HTML elements into components, but cannot resolve imports.

Perhaps the ideal solution is to create an adder for content-collections https://svelte-add.com/, and add the option to include mdsvex boilerplate. On a related note, we can add boilerplate for Shiki integration via the Svelte adder, too.

sdorra commented 3 weeks ago

@theetrain this is a neat approach. But I would like to have a similar API as the one for the MDX package. If this is not possible or if the result is not as good as with the Vite processor, we should recommend your approach (e.g. with a sample). Can we achieve a similar result with svelte.preprocess?