Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is MDX supported in SvelteKit? #251

Open
tsriram opened this issue Aug 16, 2024 · 9 comments
Open

Is MDX supported in SvelteKit? #251

tsriram opened this issue Aug 16, 2024 · 9 comments
Assignees
Labels
question Further information is requested

Comments

@tsriram
Copy link

tsriram commented Aug 16, 2024

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 sdorra self-assigned this Aug 16, 2024
@sdorra sdorra added the question Further information is requested label Aug 16, 2024
@sdorra
Copy link
Owner

sdorra commented Aug 16, 2024

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
Copy link
Author

tsriram commented Aug 17, 2024

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
Copy link
Owner

sdorra commented Aug 17, 2024

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
Copy link

theetrain commented Aug 18, 2024

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
Copy link
Owner

sdorra commented Aug 20, 2024

@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?

@git-no
Copy link

git-no commented Sep 23, 2024

@sdorra There a are some Svelte markdown-preprocessor repositories. Why not integrating an existing markdown-preprocessor code? Or do you want to develop a new markdown-preprocessor for content-collections?

@sdorra
Copy link
Owner

sdorra commented Sep 23, 2024

@git-no as far as I understand, mdsvex is a popular Markdown preprocessor in the Svelte environment, and the idea is to create an mdsvex integration for content collections.

@git-no
Copy link

git-no commented Sep 24, 2024

@sdorra MDsveX seem to me to oversized in this combination. Also the MDsveX compiler does not work quite well.

I tried today to develop a svelteMDx compiler to integrate in transform similar to compileMDX but difficulty is, frontmatter (as object or string) is not available and in document is only the body of the markdown. So I am handicapped to proceed.

@sdorra
Copy link
Owner

sdorra commented Sep 26, 2024

@git-no, the first parameter of the transform function is the document, and the document contains all fields from the schema, plus the content and the _meta field.

The schema describes the shape of the frontmatter, e.g.:

If we have the following md/mdx file:

---
title: "Functioning of the Drive of the Heart of Gold"
author: "Tricia Marie McMillan"
---

# The Heart of Gold
...

The configuration of content collections (content-collections.ts) could look like this:

import { defineCollection, defineConfig } from "@content-collections/core";
import { compileMDX } from "@content-collection/svelte-mdx";

const posts = defineCollection({
  name: "posts",
  directory: "posts",
  include: "*.md(x)?",
  schema: (z) => ({
    title: z.string(),
    author: z.string()
  }),
  transform: async (document, ctx) => {
    const content = await compileMDX(ctx, document);
    return {
      ...document,
      content,
    };
  },
});

export default defineConfig({
  collections: [posts],
});

The document that is passed to the transform function should look like the following:

{
  "title": "Functioning of the Drive of the Heart of Gold"
  "author": "Tricia Marie McMillan",
  "content": "# The Heart of Gold",
  "_meta": { ... }
}

So if you remove the content and the _meta, you have the front matter as an object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants