contentlayerdev / contentlayer

Contentlayer turns your content into data - making it super easy to import MD(X) and CMS content in your app
https://www.contentlayer.dev
MIT License
3.33k stars 200 forks source link

[suggestion] allow mdx processing without mdx-bundler #247

Open stefanprobst opened 2 years ago

stefanprobst commented 2 years ago

mdx-bundler is pretty opinionated and i would like to be able to use a simpler setup closer to the official MDX on demand guide.

it would be cool if something like the following could work with contentlayer:

import { compile } from '@mdx-js/mdx'
import withToc from '@stefanprobst/rehype-extract-toc'
import type { RawDocumentData } from 'contentlayer/source-files'
import { defineDocumentType, makeSource } from 'contentlayer/source-files'
import withSlug from 'rehype-slug'
import withFrontmatter from 'remark-frontmatter'
import withGfm from 'remark-gfm'
import { VFile } from 'vfile'
import { matter } from 'vfile-matter'

import { getTranslations } from '@/app/i18n'

const Post = defineDocumentType(() => {
  return {
    name: 'Post',
    description: 'Post',
    filePathPattern: `posts/**/*.mdx`,
    contentType: 'mdx',
    fields: {
      title: { description: 'Title', type: 'string', required: true },
      locale: { description: 'Locale', type: 'enum', options: ['en', 'de'], required: true },
    },
  }
})

export default makeSource({
  contentDirPath: 'content',
  documentTypes: [Post],
  async mdx(raw: string, sourceFilePath?: string) {
    const input = new VFile({ value: raw, path: sourceFilePath })

    matter(input)
    const { locale } = input.data['matter']
    const t = await getTranslations(locale)

    const vfile = await compile(input, {
      remarkPlugins: [withFrontmatter, withGfm],
      remarkRehypeOptions: {
        footnoteBackLabel: t('footnote-back-label'),
        footnoteLabel: t('footnote-label'),
      },
      rehypePlugins: [withSlug, withToc],
    })

    return { code: String(vfile), data: vfile.data }
  },
})
stefanprobst commented 2 years ago

i think this could look something like this: https://github.com/contentlayerdev/contentlayer/compare/main...stefanprobst:feat/mdx-md-processing