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

如何在Gatsby根路径渲染带格式的about.mdx内容?

问题描述

我是Gatsby和GraphQL的新手,正在探索相关技术。我想要将根目录下about.mdx的内容渲染到网站根路径,默认情况下Gatsby会根据about.mdx生成mysite.com/about这样的路径,但我希望网站的首页(根路径)能渲染与mysite.com/about相同的内容。

我原本的做法是在index.tsx文件中使用GraphQL提取about.mdx的内容,但将rawBody渲染到index.tsx时,显示效果和mysite.com/about由about.mdx渲染出的效果不一样,rawBody渲染的是无格式的纯文本。

效果对比

  • 错误效果(rawBody渲染):
    rawBody渲染的无格式文本
  • 期望效果(about页面的正常渲染):
    about页面的正常格式渲染

以下是我的index.tsx代码:

import React from 'react'
import { Link, graphql } from 'gatsby'
import { Wrapper, SectionTitle, Header, SectionSubTitle, SEO } from 'components'
import { Layout } from 'layouts'
import { Content } from 'layouts/components'
import Helmet from 'react-helmet'
import config from 'config/siteConfig'
import Data from 'models/Data'
import styled from 'styled-components'
import { FeaturedPosts } from 'components/FeaturedPost'

interface Props {
  data: Data
}

const HomePage = (props: Props) => {
  const { edges } = props.data.allMdx

  return (
    <Layout>
      <Helmet title={`Blog | ${config.siteTitle}`} />
      <SEO path="/" data={{ title: config.siteTitleAlt }} />
      <Header>
        <SectionTitle>
          {config.siteTitle}
          <Line />
          <SectionSubTitle>{config.siteDescription}</SectionSubTitle>
        </SectionTitle>
      </Header>
      <Wrapper>
        <Content>
         {edges.map((post) => (
              <li
                key={post.node.frontmatter.title}
                style={{ listStyleType: 'none', margin: 0 }}
              >

                  <DateTag dateTime={post.node.frontmatter.standardDate}>
                    <p>{post.node.frontmatter.date}
                    {post.node.rawBody}</p>
                  </DateTag>

                
              </li>
              
            ))}
        </Content>
      </Wrapper>
    </Layout>
  )
}
// Gatsby needs this default export to work.
// eslint-disable-next-line import/no-default-export
export default HomePage

// export const query = graphql`
//   query {
//     allMdx(
//       sort: { fields: [frontmatter___date, frontmatter___title], order: DESC }
//       limit: 10
//     ) {
//       totalCount
//       edges {
//         node {
//           fields {
//             path
//           }
//           frontmatter {
//             title
//             date(formatString: "MMMM D, YYYY")
//             standardDate: date(formatString: "YYYY-MM-DD")
//           }
//           excerpt(pruneLength: 200)
//           timeToRead
//         }
//       }
//     }
//   }
// `
export const query = graphql`
query {
  allMdx(filter: {id: {eq: "0d5c6066-a6d3-595d-8902-aedbfcdc2ce7"}, slug: {}}) {
    edges {
      node {
        id
        frontmatter {
          title
        }
        rawBody
      }
    }
  }
}
`

const Line = styled.hr`
  color: white;
  width: 5rem;
  margin: 0.5rem auto;
  height: 3px;
`

const Title = styled.span`
  margin-right: 0.5rem;
`

const DateTag = styled.time`
  color: rgba(0, 0, 0, 0.5);
`
解决方案

问题出在直接渲染rawBody——它是未经编译的原始MDX文本,自然不会解析格式。要正确渲染MDX内容,有两种可行方案:

方案一:使用MDXRenderer渲染编译后的内容(保留/about路径)

1. 确保依赖安装配置完成

如果还没安装gatsby-plugin-mdx,先执行安装命令:

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

在gatsby-config.js中配置插件:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        // 可按需添加MDX插件配置
      },
    },
  ],
}

2. 修改GraphQL查询,获取编译后的body

将查询中的rawBody替换为body(这是Gatsby编译后的MDX内容):

export const query = graphql`
query {
  allMdx(filter: {id: {eq: "0d5c6066-a6d3-595d-8902-aedbfcdc2ce7"}, slug: {}}) {
    edges {
      node {
        id
        frontmatter {
          title
        }
        body # 替换rawBody为body
      }
    }
  }
}
`

3. 引入并使用MDXRenderer组件

在index.tsx中导入MDXRenderer,并用它替代直接渲染rawBody:

import React from 'react'
import { Link, graphql } from 'gatsby'
import { MDXRenderer } from 'gatsby-plugin-mdx' // 新增导入
import { Wrapper, SectionTitle, Header, SectionSubTitle, SEO } from 'components'
import { Layout } from 'layouts'
import { Content } from 'layouts/components'
import Helmet from 'react-helmet'
import config from 'config/siteConfig'
import Data from 'models/Data'
import styled from 'styled-components'
import { FeaturedPosts } from 'components/FeaturedPost'

interface Props {
  data: Data
}

const HomePage = (props: Props) => {
  const { edges } = props.data.allMdx

  return (
    <Layout>
      <Helmet title={`Blog | ${config.siteTitle}`} />
      <SEO path="/" data={{ title: config.siteTitleAlt }} />
      <Header>
        <SectionTitle>
          {config.siteTitle}
          <Line />
          <SectionSubTitle>{config.siteDescription}</SectionSubTitle>
        </SectionTitle>
      </Header>
      <Wrapper>
        <Content>
         {edges.map((post) => (
              <li
                key={post.node.frontmatter.title}
                style={{ listStyleType: 'none', margin: 0 }}
              >
                  <h2>{post.node.frontmatter.title}</h2>
                  {/* 使用MDXRenderer渲染编译后的内容 */}
                  <MDXRenderer>{post.node.body}</MDXRenderer>
              </li>
            ))}
        </Content>
      </Wrapper>
    </Layout>
  )
}

export default HomePage

// 修改后的查询
export const query = graphql`
query {
  allMdx(filter: {id: {eq: "0d5c6066-a6d3-595d-8902-aedbfcdc2ce7"}, slug: {}}) {
    edges {
      node {
        id
        frontmatter {
          title
        }
        body
      }
    }
  }
}
`

const Line = styled.hr`
  color: white;
  width: 5rem;
  margin: 0.5rem auto;
  height: 3px;
`

const Title = styled.span`
  margin-right: 0.5rem;
`

const DateTag = styled.time`
  color: rgba(0, 0, 0, 0.5);
`

方案二:直接修改about.mdx的slug(无需修改index.tsx)

如果不需要保留/about路径,直接在about.mdx的frontmatter中设置根路径slug:

---
title: About
slug: "/"
---
# 这里是about.mdx的内容
...

这样Gatsby会自动将about.mdx渲染到根路径,无需修改index.tsx。若需要同时保留/about路径和根路径的内容,则使用方案一。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:22:47