You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gatsby搭建博客时MDX无法渲染仅显纯文本,报Element type is invalid错误

Gatsby MDX内容无法渲染为HTML的解决方案

问题核心

你当前遇到两个关键问题:

  • MDX内容以纯文本形式显示:直接渲染未编译的原始body字段,未使用MDX专用渲染组件处理
  • "Element type is invalid"错误:源于插件配置冲突、MDX组件导入错误或数据传递方式不合理

修复步骤

1. 清理gatsby-config.js的插件冲突

配置中重复注册了gatsby-plugin-mdx和gatsby-transformer-remark,会导致MDX编译逻辑混乱,修改后配置如下:

module.exports = {
  siteMetadata: {
    title: `My Online Portfolio`,
    description: `my home on the web`,
    siteUrl: `https://evilsaint.cloud`,
    social: {
      twitter: `https://twitter.com/_EvilSaint_`
    },
  },
  plugins: [
    `gatsby-plugin-image`, 
    `gatsby-plugin-sitemap`, 
    `gatsby-plugin-sharp`, 
    `gatsby-transformer-sharp`,
    {
      resolve: 'gatsby-plugin-mdx',
      options: {
        extensions: [`.mdx`, `.md`],
        gatsbyRemarkPlugins: [
          {
            resolve: `gatsby-remark-highlight-code`,
            options: {
              terminal: "ubuntu",
            },
          },
        ],
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        "name": "images",
        "path": "./src/images/"
      },
      __key: "images"
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        "name": "pages",
        "path": "./src/pages/"
      },
      __key: "pages"
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        "name": `blogs`,
        "path": `${__dirname}/src/blog/`,
      },
      __key: "blogs"
    }
  ]
};

2. 修改createPages逻辑,传递slug而非完整node

不要将整个MDX节点传入context,仅传递slug即可,让模板通过graphql查询编译后的MDX内容:

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const path = require('path')

  const result = await graphql(
    `
    query AllQueries {
      site {
        siteMetadata {
          title
        }
      }
      allMdx(sort: {fields: [frontmatter___date], order: DESC}) {
        nodes {
          fields {
            slug
          }
          frontmatter {
            date(formatString: "Do MMMM YYYY ")
            title
            description
          }
        }
      }
    }
  `
  )

  const blogPostTemplate = path.resolve(`./src/templates/blog-post.js`)
  const articles = result.data.allMdx.nodes
  
  articles.forEach((node, index) => {
    createPage({
      path: `/blog${node.fields.slug}`,
      component: blogPostTemplate,
      context: {
        slug: node.fields.slug,
        prev: index === 0 ? null : articles[index - 1],
        next: index === articles.length - 1 ? null : articles[index + 1]
      },
    })
  })
}

3. 改造博客模板,用MDXRenderer渲染编译内容

首先安装必要依赖(未安装时执行):

npm install @mdx-js/react gatsby-plugin-mdx

修改模板代码,通过graphql查询MDX的编译后内容,并用MDXRenderer渲染:

import React from "react";
import { Link, graphql } from "gatsby";
import { MDXRenderer } from "gatsby-plugin-mdx";
import Layout from "../components/layout";

function BlogPost({ data, pageContext }) {
  const post = data.mdx
  const prev = pageContext.prev 
  ? {
    url : `${pageContext.prev.fields.slug}`,
    title : pageContext.prev.frontmatter.title 
  } : null

  const next = pageContext.next 
  ? {
    url : pageContext.next.fields.slug,
    title : pageContext.next.frontmatter.title 
  } : null

  return (
   <Layout>
      <div className="card">
         <Link className="card-link" to={`.${post.fields.slug}`}>              
         <h2 className="card-title">{post.frontmatter.title}</h2>
         </Link>
         <p className="card-date">{post.frontmatter.date}</p>
         <p className="card-description">{post.frontmatter.description}</p>
         
         <MDXRenderer>{post.body}</MDXRenderer>
         
         <nav>
         {next && 
         <Link to={`..${next.url}`} className="previous">
            <span>&lt; {next.title} </span>
         </Link>
         }
         {prev && 
            <Link to={`..${prev.url}`} className="next">
               <span>{prev.title} &gt;</span>
            </Link>
         }
         </nav>
      </div>
   </Layout>
  )
}

export const query = graphql`
  query($slug: String!) {
    mdx(fields: { slug: { eq: $slug } }) {
      fields {
        slug
      }
      frontmatter {
        date(formatString: "Do MMMM YYYY ")
        title
        description
      }
      body
    }
  }
`

export default BlogPost

4. 验证MDX v2兼容性

确保gatsby-plugin-mdx版本为4.x及以上(支持MDX v2),查看package.json:

"gatsby-plugin-mdx": "^4.0.0"

版本过低时执行升级:

npm update gatsby-plugin-mdx

修复逻辑说明

  • 重复插件会干扰Gatsby的MDX编译流程,必须清理
  • 直接传递完整节点无法获取编译后的MDX组件,模板内查询才能拿到正确结果
  • MDXRenderer是Gatsby专用的MDX渲染组件,可将MDX语法转换为HTML元素和React组件

内容的提问来源于stack exchange,提问作者Berkay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 08:15:35