简体   繁体   English

MDX 博客仅显示 markdown 内容,而不是在 Next JS 中使用来自 `@mdx-js/react` 的 `MDXProvider` 进行渲染

[英]MDX blog just displays markdown content instead of rendering it while using `MDXProvider` from `@mdx-js/react` in Next JS

I am making a blog with MDX & Next.js but I am unable to render Markdown content.我正在使用MDX & Next.js创建博客,但我无法呈现 Markdown 内容。 The blog post just shows markdown content as string .博文仅将 markdown 内容显示为string

Here's my complete source code → https://github.com/deadcoder0904/blog-mdx-next/这是我的完整源代码 → https://github.com/deadcoder0904/blog-mdx-next/

I have the following folder structure:我有以下文件夹结构:

.
|-- README.md
|-- components
|   `-- Image.js
|-- next.config.js
|-- package-lock.json
|-- package.json
|-- pages
|   |-- _app.js
|   |-- blog
|   |   `-- [slug].js
|   |-- dark.css
|   |-- index.js
|   `-- new.css
|-- posts
|   |-- blog
|   |   |-- hello-world
|   |   |   |-- Rustin_Cohle.jpg
|   |   |   `-- index.mdx
|   |   `-- shit-world
|   |       `-- index.mdx
|   `-- tutorials
|       `-- console-log-in-javascript
|           `-- index.mdx
|-- prettier.config.js
`-- utils
    `-- mdxUtils.js

I have all my content in posts/ folder.我的所有内容都在posts/文件夹中。

I have 2 folders in it: blog/ & tutorials/我有 2 个文件夹: blog/ & tutorials/

Each post is in their own folder inside of blog/ or tutorials/ .每篇文章都在blog/tutorials/中各自的文件夹中。 It looks like:看起来像:

博客档案

I want to render my posts/blog/hello-world/index.mdx post at blog/hello-world location so I made blog/[slug].js file.我想在blog/hello-world位置呈现我的posts/blog/hello-world/index.mdx帖子,所以我制作了blog/[slug].js文件。

The contents of it are as follows:内容如下:

pages/blog/[slug].js页面/博客/[slug].js

import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { MDXProvider } from '@mdx-js/react'

import { BLOG_PATH, blogFilePaths } from '../../utils/mdxUtils'
import { Image } from '../../components/Image'

const MDXComponents = { Image }

const Blog = ({ source, frontMatter }) => {
    return (
        <div>
            <h1>{frontMatter.title}</h1>
            <MDXProvider components={MDXComponents}>{source}</MDXProvider>
        </div>
    )
}

export async function getStaticPaths() {
    const paths = blogFilePaths.map((path) => {
        const split = path.split('/')
        const slug = split[split.length - 2]
        return {
            params: {
                slug,
            },
        }
    })

    return {
        paths,
        fallback: false,
    }
}

export const getStaticProps = async ({ params }) => {
    const { slug } = params
    const blogFilePath = path.join(BLOG_PATH, `/blog/${slug}/index.mdx`)

    const source = fs.readFileSync(blogFilePath)
    const { content: mdx, data } = matter(source)

    if (!blogFilePath) {
        console.warn('No MDX file found for slug')
    }

    return {
        props: {
            source: mdx,
            frontMatter: data,
        },
    }
}

export default Blog

The important part is:重要的部分是:

<MDXProvider components={MDXComponents}>{source}</MDXProvider>

I thought this would render markdown content but it only displays markdown content as a string .我认为这会呈现 markdown 内容,但它只将 markdown 内容显示为string

You can check the output at https://codesandbox.io/s/github/deadcoder0904/blog-mdx-next?file=/pages/blog/%5Bslug%5D.js by clicking any blog post.您可以通过单击任何博客文章在https://codesandbox.io/s/github/deadcoder0904/blog-mdx-next?file=/pages/blog/%5Bslug%5D.js查看 output。

It displays the following when I click on Hello World post:当我点击Hello World帖子时,它会显示以下内容:

你好世界

How do I actually render the content?我如何实际呈现内容?

I looked at other Github repos like Tailwind CSS Blog & it works fine for them but I am not sure how it works sadly:(我查看了其他 Github 回购协议,例如Tailwind CSS 博客,它对他们来说工作正常,但我不确定它是如何工作的:(

I do know that I have to convert the source prop in Blog or mdx in getStaticProps but I don't see Tailwind doing it either.我知道我必须在Blog中转换source prop 或在getStaticProps中转换mdx但我也没有看到Tailwind 这样做。

I think this is what you're looking for https://github.com/vercel/next.js/discussions/13901我想这就是你要找的https://github.com/vercel/next.js/discussions/13901

You'll need to install this package npm i next-mdx-remote and make these changes to your code:您需要安装此 package npm i next-mdx-remote并对您的代码进行以下更改:

import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import renderToString from 'next-mdx-remote/render-to-string'
import hydrate from 'next-mdx-remote/hydrate'

import { BLOG_PATH, blogFilePaths } from '../../utils/mdxUtils'
import { Image } from '../../components/Image'

const components = { Image }

const Blog = ({ source, frontMatter }) => {
    const content = hydrate(source, { components })

    return (
        <div>
            <h1>{frontMatter.title}</h1>
            {content}
        </div>
    )
}

...

export const getStaticProps = async ({ params }) => {
    const { slug } = params
    const blogFilePath = path.join(BLOG_PATH, `/blog/${slug}/index.mdx`)

    const source = fs.readFileSync(blogFilePath, 'utf-8');
    const { content, data } = matter(source);
    const mdxSource = await renderToString(content, { components });

    if (!blogFilePath) {
        console.warn('No MDX file found for slug')
    }

    return {
        props: {
            source: mdxSource,
            frontMatter: data,
        },
    }
}

export default Blog

But then you will have an issue when referencing assets inside your mdx files, the tailwind blog solves this by adding a loader for assets , unfortunately next-mdx-remote doesn't seem to support imports inside MDX (or probably need a specific configuration) so you'll have to move your images to the public folder , something like public/blog/Rustin_Cohle.jpg但是当你在你的 mdx 文件中引用资产时你会遇到一个问题,顺风博客通过为资产添加一个加载器来解决这个问题,不幸的是next-mdx-remote似乎不支持在 MDX 中导入(或者可能需要特定的配置)所以你必须将你的图像移动到public 文件夹,比如public/blog/Rustin_Cohle.jpg

The difference with the tailwind blog is that you're using Dynamic SSG tailwind 博客的不同之处在于您使用的是 Dynamic SSG

Also, there is this another approach that I didn't test completely https://github.com/vercel/next.js/issues/9524#issuecomment-580239600此外,还有另一种我没有完全测试的方法https://github.com/vercel/next.js/issues/9524#issuecomment-580239600

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 RSS 添加到 Next.js MDX 博客,同时使用 Node JS 的 `rss` 模块。 如何将 MDX 转换为 HTML? - Add RSS to Next.js MDX Blog while using `rss` module for Node JS . How do I convert MDX to HTML? 找不到模块“@mdx-js/mdx”——盖茨比 - Cannot find module '@mdx-js/mdx' - Gatsby 如何正确使用 @mdx-js/loader 和 create-react-app? - How to correctly use @mdx-js/loader with create-react-app? 在 Next.js 中使用带有 MDX 的 Remark 和 Rehype 插件(使用 @next/mdx) - Using Remark and Rehype plugins with MDX in Next.js (with @next/mdx) "在 Next JS 中使用 `next-mdx-remote` 时,如何在`public\/` 文件夹之外的`.mdx` 文件中使用图像?" - How to use images in a `.mdx` file outside of `public/` folder while using `next-mdx-remote` in Next JS? .mdx 文件中的 React 组件和数学表达式在 Next.js 应用程序中未正确呈现 - React components and math expressions in .mdx file are not rendering correctly in Next.js application 使用 Gatsby JS 和 Markdown MDX,如何在 MDX 中呈现 HTML5 动画? - Using Gatsby JS and markdown MDX, how can I render HTML5 animations in MDX? 使用 `.js` 文件从 `.mdx` 文件中读取 `frontmatter` 中的值 - Read the values from `frontmatter` from `.mdx` files using a `.js` file Taiwlind CSS:样式不会在生产中加载,在开发中工作。 将 Next.js 与 MDX 结合使用 - Taiwlind CSS: Styles don't load in production, works in dev. Using Next.js with MDX 在 next-mdx-remote MDX 组件中使用 react-query? - Using react-query inside next-mdx-remote MDX Components?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM