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

使用react-markdown时如何为react-syntax-highlighter添加文件名标题

实现方案

第一步:调整Markdown代码块书写格式

你可以直接在代码块的语言标识后追加title参数,格式如下:

```jsx title="App.js"
const App = () => {
  const [todos, setTodos] = useState([
    { text: "Buy Food", isCompleted: false },
    { text: "Learn React", isCompleted: true },
    { text: "Build todo app", isCompleted: true }
  ]);

  //...
}
这种写法属于Markdown代码块的通用扩展规范,不需要额外安装特殊插件即可解析。

### 第二步:修改Article.js中的代码渲染逻辑
我们需要从代码块的node节点中提取meta信息,解析出title值后自定义渲染逻辑,可选择仅显示标题、仅显示语言标识或者两者共存。修改后的完整代码如下:
```jsx
import React from "react"
import ReactMarkdown from "react-markdown"
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism"
import rehypeRaw from "rehype-raw"
import remarkGfm from "remark-gfm"
import remarkSlug from "remark-slug"
import "../../../styles/language.css"

const ArticleContent = ({ content }) => {
  return (
    <ReactMarkdown
      remarkPlugins={[remarkGfm, remarkSlug]}
      rehypePlugins={[rehypeRaw]}
      children={content}
      linkTarget="_blank"
      transformImageUri={uri =>
        uri.startsWith("http") ? uri : `${process.env.GATSBY_ROOT_URL}${uri}`
      }
      components={{
        code({ node, inline, className, children, ...props }) {
          const match =
            className !== undefined
              ? className.replace("language-", "")
              : "code"
          // 新增逻辑:解析代码块meta中的title参数
          const meta = node?.meta || ''
          const titleMatch = meta.match(/title="([^"]+)"/) || meta.match(/title=([^\s]+)/)
          const codeTitle = titleMatch ? titleMatch[1] : null

          return !inline && match ? (
            <div className="relative">
              {(match !== "shell-session" || match === null) && (
                <p
                  className={`code-hightlight font-jost text-sm font-light tracking-wide rounded-b absolute right-2 -top-5 px-2 py-1 bg-tertiary`}
                >
                  {/* 优先显示自定义标题,没有标题则 fallback 显示语言标识 */}
                  {codeTitle || match}
                </p>
              )}
              <SyntaxHighlighter
                children={String(children).replace(/\n$/, "")}
                style={vscDarkPlus}
                language={match}
                PreTag="div"
                {...props}
              />
            </div>
          ) : (
            <code className={`rounded-md ${className}`} {...props}>
              {children}
            </code>
          )
        },
      }}
    />
  )
}

export default ArticleContent

可选优化

如果需要同时展示文件名和语言标识,只需要调整标签结构,分别渲染codeTitle和match两个变量即可,也可以额外增加文件图标、调整对齐方式适配你的设计风格。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:36:02