赞
踩
Next.js 作为一款开箱即用的 React 框架,因其优秀的服务器渲染能力和灵活的配置方式,已经吸引了大量的开发者。同时,Markdown 作为一种轻量级的标记语言,以其简洁的语法和强大的功能,已经成为了写作的首选工具。那么,如何在 Next.js 中渲染 Markdown 呢?这可能会让一些开发者感到困惑,但其实这个过程比你想象的要简单得多。在这篇文章中,我将会详细地解释如何在 Next.js 中渲染 Markdown,希望能为那些正在寻找解决方案的开发者提供一些参考和帮助。
Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换为有效的 HTML 文档。它可以用来制作说明文档、网页内容、电子书等。它的设计目标是易读性和易写性,以及尽可能的兼容性。Markdown 的语法由一些简单的符号组成,如井号(#)、星号(*)和破折号(-)。
MDX 则是一种扩展 Markdown 的语言,它允许你在 Markdown 文档中直接编写 JSX,并通过组件来导入和使用。这意味着你可以在 Markdown 中使用 React 组件,或者在 JSX 中使用 Markdown。MDX 非常适合用于创建复杂的交互式文档、幻灯片、博客等。
项目基于 create-next-app 搭建,安装了 TailwindCSS。
PS E:\> pnpm create create-next-app@latest
√ What is your project named? ... next-mdx
√ Would you like to use TypeScript? ... Yes
√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... Yes
√ Would you like to use `src/` directory? ... No
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to customize the default import alias (@/*)? ... No
安装渲染 MDX 所需要的包:
pnpm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
在根目录创建一个 mdx-components.tsx
文件:
import type { MDXComponents } from 'mdx/types'
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
}
}
这里解构的 components
可以是 HTML 标签,也可以是我们的 jsx/tsx 文件,比如我新建 components/button.tsx
文件:
const Button = ({ children }: { children: React.ReactNode }) => {
return (
<button className="test-xs px-4 py-2 bg-zinc-950 text-white rounded-md">
{children}
</button>
);
};
export default Button;
修改 mdx-components.tsx
文件:
import type { MDXComponents } from "mdx/types";
import Button from "@/components/button";
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
h1: (props) => <h1 className="text-3xl font-bold">{props.children}</h1>,
Button,
};
}
上面代码给 h1
标签添加了两个 class:text-3xl font-bold
设置一级标题字体大小与加粗,并且导入了 Button 组件。
修改根目录中的 next.config.js
文件:
const withMDX = require("@next/mdx")();
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ["js", "jsx", "mdx", "ts", "tsx"],
};
module.exports = withMDX(nextConfig);
然后就可以在项目中愉快的渲染 .mdx
文件了。
新建 app/mdx/page.mdx
:
export const metadata = {
title: 'mdx'
}
# mdx-remote
- 1
- 2
- 3
<Button>button</Button>
由于我们前面在 mdx-components.tsx
中添加了 Button 组件,于是可以直接在 mdx 中使用。
export const metadata
用于设置页面元数据,这些元数据对于SEO(搜索引擎优化)非常重要。
访问 /mdx
页面,你将会看到以下页面,并且网页的标题也被修改为了 mdx
:
如果 Markdown 或 MDX 文件或内容位于其他位置,比如本地文件夹、远程 URL、数据库等,则需要在服务器上动态获取它。
有两个常用的库,一个是 next-mdx-remote
一个是 contentlayer
,接下来我将演示如何在 Next.js 中使用 next-mdx-remote
来渲染 mdx
文件。
安装 next-mdx-remote
:
pnpm install next-mdx-remote
新建 components/mdx-components.tsx
文件:
"use client"; import { MDXRemote, MDXRemoteProps } from "next-mdx-remote"; import Button from "./button"; export default function Mdx(props: MDXRemoteProps) { return ( <MDXRemote {...props} components={{ h1: (props) => { return <h1 className="text-3xl font-bold">{props.children}</h1>; }, Button, }} /> ); }
创建文件 app/[slug]/page.tsx
文件:
import { MDXRemote } from "next-mdx-remote"; import { serialize } from "next-mdx-remote/serialize"; import fs from "fs"; import Mdx from "@/components/mdx-components"; import { notFound } from "next/navigation"; interface PostProps { params: { slug: string; }; } const PostsPage = async ({ params: { slug } }: PostProps) => { try { const postFile = fs.readFileSync(`posts/${slug}.mdx`); const source = await serialize(postFile, { parseFrontmatter: true }); return ( <div> <Mdx {...source} /> </div> ); } catch { notFound(); } }; export default PostsPage; async function getPostBySlug(slug: string) { const postFile = fs.readFileSync(`posts/${slug}.mdx`); const source = await serialize(postFile, { parseFrontmatter: true }); return source; } export async function generateMetadata({ params }: PostProps) { const { frontmatter } = await getPostBySlug(params.slug); return frontmatter; }
serialize
函数将读取到的 MDX 文件内容进行解析和转化,可以将 MDX 格式的文件转化为可以在 React 中直接使用的 JSX 格式。notFound
函数进入 404 页面。Mdx
组件将解析后的 MDX 内容进行渲染,展示在页面上。generateMetadata
函数会提取 MDX 文件的 frontmatter 元数据,这些元数据通常用于存储一些关于文档的信息,如作者、创建日期等。generateMetadata
函数导出,便可以在页面中渲染元数据。新建 posts/mdx-remote.mdx
文件:
---
title: mdx-remote
description: description
data: 2023-12-19
authro: 远小帅
---
# mdx-remote
- 1
- 2
- 3
<Button>button</Button>
在文件开头我使用了三个破折号包括了一段数据,这被称为 Frontmatter,采用 YAML
格式,用来描述文档的元数据。
此时访问 /mdx-remote
页面,便可以看到和刚才图片相同的页面。
在这篇文章中,我详细介绍了如何在 Next.js 中渲染 Markdown 和 MDX 文件。希望这篇文章能够帮助你更好地理解和使用 Markdown 和 MDX 在 Next.js 中的应用,为你的开发工作带来便利。
下一篇文章我将开发一个具有 SEO 优化的博客实战项目,使用 MDX 渲染,有感兴趣的小伙伴可以关注一下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。