Open seancdavis opened 2 years ago
This would also be helpful in writing scripts to generate static files (like writing an RSS feed xml
file) where you may want some form of the compiled body available for consumption.
Does anyone have a solution for this at the moment? Working on adding an RSS feed and unable to render the content from MDX source at the moment.
I've just ran into the same issue. I am trying to take posts written in MDX and add them to an RSS feed, but I just can't can't plain HTML back. Anyone had any luck with this?
I'm not yet convinced whether we should actually make this a built-in feature (in order to keep Contentlayer simple) but this should already be possible using the following approach:
import { defineDocumentType } from 'contentlayer/source-files'
import { bundleMDX } from 'mdx-bundler'
import * as ReactDOMServer from 'react-dom/server'
import { getMDXComponent } from 'mdx-bundler/client/index.js'
const mdxToHtml = async (mdxSource: string) => {
const { code } = await bundleMDX({ source: mdxSource })
const MDXLayout = getMDXComponent(code)
// TODO add your own components here
const element = MDXLayout({ components: {} })!
const html = ReactDOMServer.renderToString(element)
return html
}
const Post = defineDocumentType(() => ({
name: 'Post',
filePathPattern: `posts/**/*.mdx`,
contentType: 'mdx',
fields: {
title: {
type: 'string',
required: true,
},
},
computedFields: {
mdxHtml: {
type: 'string',
resolve: (doc) => mdxToHtml(doc.body.raw),
},
},
}))
I've also added an example here.
Thanks for this example.
I've tried this and I'm running into issues. Seems if my components object contains anything that requires jsx, it throws an error. I've set up a branch in my repo to show this.
https://github.com/ThePaulMcBride/paulmcbride.com/tree/feature/full-rss-feed
Am I doing something dumb?
I’m asking myself the same thing @ThePaulMcBride 😅 Have you found a fix? I can’t get it to build, getting the same error when using JSX:
The JSX syntax extension is not currently enabled
The
esbuild
loader for this file is currently set tojs
but it must be set tojsx
to be able to parse JSX syntax. You can use"loader: { '.js': 'jsx' }"
to do that.
Not too sure where I should change the loader for next.js, but will keep looking.
I have had no luck either. I'm currently just living with a crappy rss feed for now.
I used some native ReactDOMServer functions to handle this. Since I use mdx components in my content, I had to create some RSS feed specific components to use in order to render them as something that would be reasonable in an RSS feed.
Take a look at this script I wrote that builds the feed:
https://github.com/pmarsceill/this-modern-web/blob/main/scripts/rss-generator.mjs
An
mdx
field delivers an object withraw
input andcode
output, which can be passed to a Contentlayer method to render it as a component.It would be great to also have the HTML code (without interactivity or the ability to hydrate).
I would personally like this as a way to use Contentlayer outside a dynamic/server-side context (i.e. in a non-Next project). But we've also heard a scenario in which someone may want to render content statically to an XML feed where the code/interactivity is irrelevant, but the content (along with the semantic markup) is important.