Add RSS to Next.js MDX Blog while using `rss` module for Node JS . How do I convert MDX to HTML?

369 views Asked by At

Currently, I am having an issue with converting MDX to HTML.

I'm doing it for Tailwind Blog

The complete code on Github → https://github.com/tailwindlabs/blog.tailwindcss.com

Here's the relevant code:

scripts/build-rss.js

import fs from 'fs'
import path from 'path'
import getAllPostPreviews from '../src/getAllPostPreviews'

import RSS from 'rss'

const siteUrl = 'https://blog.tailwindcss.com'

const feed = new RSS({
  title: 'Blog – Tailwind CSS',
  site_url: siteUrl,
  feed_url: `${siteUrl}/feed.xml`,
})

getAllPostPreviews().forEach(({ link, module: { meta, default: html } }) => {
  console.log(html)
  const postText = `<div style="margin-top=55px; font-style: italic;">(The post <a href="${siteUrl + link}">${meta.title}</a> appeared first on <a href="${siteUrl}">Tailwind CSS Blog</a>.)</div>`;
  feed.item({
    title: meta.title,
    guid: link,
    url: `https://blog.tailwindcss.com${link}`,
    date: meta.date,
    description: meta.description,
    custom_elements: [{
      "content:encoded": html + postText
    }].concat(meta.authors.map((author) => ({ author: [{ name: author.name }] }))),
  })
})

fs.writeFileSync('./out/feed.xml', feed.xml({ indent: true }))

The html variable logs to the console:

[Function: MDXContent] { isMDXComponent: true }

How do I get plain HTML?

1

There are 1 answers

0
deadcoder0904 On BEST ANSWER

This was a little complicated than I thought it would be. Anyways here are the changes I made to get the HTML:

I added resourceQuery: /rss/ to next.config.js like:

next.config.js

{
    resourceQuery: /rss/,
    use: [
        ...mdx,
        createLoader(function (src) {
            return this.callback(null, src)
        }),
    ],
},

Used the above rss query in getAllPostPreviews.js by adding a new function getAllPosts like:

getAllPostPreviews.js

export function getAllPosts() {
  return importAll(require.context('./pages/?rss', true, /\.mdx$/)).sort((a, b) =>
    dateSortDesc(a.module.meta.date, b.module.meta.date)
  )
}

I exported mdxComponents from Post.js like:

Post.js

export const mdxComponents = {
  ...
}

Finally, changed scripts/build-rss.js to use ReactDOMServer.renderToStaticMarkup() by wrapping it in MDXProvider like:

import ReactDOMServer from 'react-dom/server'
import { MDXProvider } from '@mdx-js/react'
import { mdxComponents } from '../src/components/Post'
import { getAllPosts } from '../src/getAllPostPreviews'

getAllPosts().forEach(({ link, module: { meta, default: Content } }, i) => {
  const mdx = <MDXProvider components={mdxComponents}><Content /></MDXProvider>
  const html = ReactDOMServer.renderToStaticMarkup(mdx)
  ...
}

Got the idea from https://ianmitchell.dev/blog/building-a-nextjs-blog-rss & https://github.com/IanMitchell/ianmitchell.dev