Next.js第二十章(MDX)

MDX

MDX是一种将Markdown和React组件混合在一起的语法,它可以在Markdown中使用React组件,从而实现更复杂的页面。另外就是我们在编写技术文档或者博客的时候,配合SSG模式,更喜欢用Markdown来编写,MDX他正好将MarkdownReact组件混合在一起,实在是方便至极。

安装依赖

bash 复制代码
npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx

启用MDX功能

1.next.config.js配置以下内容
ts 复制代码
//next.config.js    
import type { NextConfig } from "next";
import createMDX from '@next/mdx'
const withMDX = createMDX({
    //extension: /\.(md|mdx)$/ 默认只支持mdx文件,如果想额外支持md文件编写次行代码。
});
const nextConfig: NextConfig = {
  reactCompiler: true,
  pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
};
export default withMDX(nextConfig);
2.根目录下面创建mdx-components.tsx文件
tsx 复制代码
import type { MDXComponents } from 'mdx/types'
 
const components: MDXComponents = {}
 
export function useMDXComponents(): MDXComponents {
  return components
}

创建文件

bash 复制代码
 my-project
  ├── app
  │   └── mdx-page
  │       └── page.(mdx/md)
  |── mdx-components.(tsx/js)
  └── package.json

代码高亮

打开编辑器-插件市场-搜索MDX-安装MDX插件

基础使用

可以支持(Markdown语法 + React组件 + HTML标签)

mdx 复制代码
# welcome to MDX

这是一段文字,**他加粗了**,并且有重点内容`important`。

- one
- two
- three


<div className='bg-red-500'>
  <p>自定义标签</p>
</div>

引入自定义组件

引入自定义组件一定要跟md语法之间空一行,否则会报错

src/app/home/page.mdx

mdx 复制代码
import MyComponent from './my-component'; //引入自定义组件一定要跟md语法之间空一行,否则会报错。

# welcome to MDX

这是一段文字,**他加粗了**,并且有重点内容`important`。

- one
- two
- three


<div className='bg-red-500'>
  <p>自定义标签</p>
</div>

<MyComponent />

mdx文件无法实现一些复杂的交付逻辑,如果有复杂的交付逻辑,我们可以使用React组件来实现,然后在mdx文件中引入即可。

tsx 复制代码
//src/app/home/my-component.tsx
'use client'
import { useState } from 'react';
export default function MyComponent() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

全局样式

如果你希望在这个项目中修改所有的MDX文件的样式,你可以使用mdx-components.tsx文件来修改。

tsx 复制代码
//mdx-components.tsx
import type { MDXComponents } from 'mdx/types'
 
const components: MDXComponents = {
    h1: ({ children }) => <h1 className='text-2xl text-red-400 font-bold'>{children}</h1>, //# 代表h1 你可以自定义修改样式
    li: ({ children }) => <li className='list-disc text-blue-500 list-inside'>{children}</li>, //- 代表li 你可以自定义修改样式
    //...你可以自定义修改更多的样式
}
 
export function useMDXComponents(): MDXComponents {
  return components
}

远程加载mdx/md文件

如果你的MDX文件存储在远程服务器上,你可以使用远程mdx来加载文件。

bash 复制代码
npm install next-mdx-remote-client
tsx 复制代码
//src/app/home/page.tsx
import { MDXRemote } from 'next-mdx-remote-client/rsc'
export default async function Home() {
  const res = await fetch('https://nextjs-docs-henna-six.vercel.app/xm.mdx') //链接是彩蛋
  const source = await res.text()
  return (
      <MDXRemote source={source} />
  );
}
相关推荐
kyriewen9 小时前
我踩了3次同一个坑才明白:JavaScript里比0.1+0.2更隐蔽的5个数字陷阱
前端·javascript·面试
徐小夕9 小时前
表格、文档、甘特、大屏、表单一站打通:pxcharts超级表格4.0正式上线!
前端·算法·github
用户594404103569 小时前
Vue3 + TypeScript + Leaflet.js 实战:构建企业级地理信息应用
前端
kyson_9 小时前
一次搭好 ESLint + Prettier + Husky + lint-staged 前端代码工作流
前端
zhifou1234569 小时前
Vue基础(二)
前端·javascript·vue.js
两只羊ovo10 小时前
手写一个最小版 Claude Code:从任务拆解到 Agent Loop 转起来
前端
给个offer养家糊口10 小时前
抽离 elpis npm 包
前端
默_笙10 小时前
🙃 我让爬虫终于看到了我的网站,后端同事说"这也行?"(下):App Router 全栈实战
前端·javascript
葡萄城技术团队10 小时前
一个单元格放置两个日期选择器:用 SpreadJS CellButtons 录入日期范围
前端
马可家的菠萝11 小时前
自动保存已经有了,为什么笔记软件还需要“历史版本”?
前端·后端·架构