在Next.js渲染Markdown竟然如此简单

Next.js 作为一款开箱即用的 React 框架,因其优秀的服务器渲染能力和灵活的配置方式,已经吸引了大量的开发者。同时,Markdown 作为一种轻量级的标记语言,以其简洁的语法和强大的功能,已经成为了写作的首选工具。那么,如何在 Next.js 中渲染 Markdown 呢?这可能会让一些开发者感到困惑,但其实这个过程比你想象的要简单得多。在这篇文章中,我将会详细地解释如何在 Next.js 中渲染 Markdown,希望能为那些正在寻找解决方案的开发者提供一些参考和帮助。

什么是 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 文件了。

新建 src/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

2023-12-19_14-44-34.png

Remote 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;
}
  1. 读取指定的MDX文件:通过网页的 URL 参数,使用 Node.js 的文件系统模块 fs 来读取 MDX 文件。
  2. 解析 MDX 文件:使用 serialize 函数将读取到的 MDX 文件内容进行解析和转化,可以将 MDX 格式的文件转化为可以在 React 中直接使用的 JSX 格式。
  3. 处理错误:如果在读取或解析文件的过程中出现错误(例如文件不存在),则会调用 notFound 函数进入 404 页面。
  4. 渲染 MDX 内容:使用自定义的 Mdx 组件将解析后的 MDX 内容进行渲染,展示在页面上。
  5. 提取MDX文件的元数据:generateMetadata 函数会提取 MDX 文件的 frontmatter 元数据,这些元数据通常用于存储一些关于文档的信息,如作者、创建日期等。
  6. 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 渲染,有感兴趣的小伙伴可以关注一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/232491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SE-Net:Squeeze-and-Excitation Networks(CVPR2018)

文章目录 AbstractIntroduction表征的重要性以前的方向本文提出 Related WorkDeeper ArchitectureAlgorithmic Architecture SearchAttention and gating mechanisms Squeeze-and-Excitation BlocksSqueeze: Global Information EmbeddingExcitation: Adaptive RecalibrationIn…

2023长三角(芜湖)人工智能数字生态峰会成功召开!

聚焦当下&#xff0c;共议数字时代发展&#xff1b;瞩目未来&#xff0c;共谋数字生态蓝图。12月11日&#xff0c;2023长三角&#xff08;芜湖&#xff09;人工智能数字生态峰会暨2023长三角&#xff08;芜湖&#xff09;人工智能视觉算法大赛颁奖典礼在芜湖宜居国际博览中心盛…

如何使用AnyTXT Searcher实现远程办公速查异地电脑文件提升工作效率

如何使用AnyTXT Searcher实现远程办公速查异地电脑文件提升工作效率 前言1. AnyTXT Searcher1.1 下载安装AnyTXT Searcher 2. 下载安装注册cpolar3. AnyTXT Searcher设置和操作3.1 AnyTXT结合cpolar—公网访问搜索神器3.2 公网访问测试 4. 固定连接公网地址 前言 你是否遇到过…

飞速(FS)100G ZR4 光模块80km长距离传输

如今&#xff0c;100G QSFP28光模块已经被广泛部署在100m到40km的范围内。然而&#xff0c;传统的100G QSFP28模块面临一个挑战&#xff0c;因为它们的设计仅限于不超过40km的距离。超出此范围&#xff0c;色散、光衰减等问题就会增加&#xff0c;导致信噪比&#xff08;SNR&am…

八股文打卡day3——计算机网络(3)

面试题&#xff1a;请讲一下四次挥手的过程&#xff1f; 1.客户端发送FIN数据包给服务器&#xff0c;表示客户端不再发送数据给服务器&#xff0c;想要断开这个方向的连接。 2.服务器收到客户端的FIN包之后&#xff0c;发送ACK包给客户端&#xff0c;对收到的FIN包进行收到确认…

13. 从零用Rust编写正反向代理, HTTP中的压缩gzip,deflate,brotli算法

wmproxy wmproxy是由Rust编写&#xff0c;已实现http/https代理&#xff0c;socks5代理&#xff0c; 反向代理&#xff0c;静态文件服务器&#xff0c;内网穿透&#xff0c;配置热更新等&#xff0c; 后续将实现websocket代理等&#xff0c;同时会将实现过程分享出来&#xff…

构建智慧储能物联网,4G工业路由器远程监测在线管理

物联网技术的发展为智慧储能管理带来了革命性的变化。其中&#xff0c;4G工业路由器IR5000通过丰富的连接能力如串口RS485/232或网口的方式&#xff0c;实现了与储能现场各设备的连接&#xff0c;包括电表、电能检测器、防孤岛装置、BMS电池管理系统、监控服务器、储能控制器、…

WEB渗透—PHP反序列化(五)

Web渗透—PHP反序列化 课程学习分享&#xff08;课程非本人制作&#xff0c;仅提供学习分享&#xff09; 靶场下载地址&#xff1a;GitHub - mcc0624/php_ser_Class: php反序列化靶场课程&#xff0c;基于课程制作的靶场 课程地址&#xff1a;PHP反序列化漏洞学习_哔哩…

xcrun: error: invalid active developer path

macOS升级完成后出现 xcrun: error: invalid active developer path问题。 xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun这是由于 Xcode command line tools 丢…

Python-Selenium-使用 pywinauto 实现 Input 上传文件

当前环境&#xff1a;Win10 Python3.7 pywinauto0.6.8&#xff0c;selenium3.14.1 示例代码 from pywinauto import Desktop import osapp Desktop() dialog app[打开] dialog[Edit].set_edit_text(os.getcwd() .\\example-01.jpg) dialog[Button].click() 其他方法&…

喜报|棱镜七彩获评江苏省专精特新中小企业

近日&#xff0c;江苏省工业和信息化厅发布《关于江苏省2023年专精特新中小企业和2020年度专精特新企业复核通过企业名单的公示》&#xff0c;棱镜七彩成功入选2023年江苏省省级专精特新中小企业名单。 图 2023年省级专精特新中小企业公式名单节选 “专精特新”是国家为鼓励中…

Python纯净式下载与安装

1. 下载 Download Python | Python.org 建议下老版本些的&#xff0c;毕竟求稳。 点击需要的版本&#xff0c;然后滑倒最下面&#xff0c;可以看到不同系统对应的下载选项&#xff1a; 2. 安装 如果下载慢的话&#xff0c;可以复制链接到迅雷下载&#xff0c;下载完成后&…

这个食堂管理大招,再不知道就晚了!

随着社会的不断发展&#xff0c;餐饮行业也在不断创新和进步。在这个数字化时代&#xff0c;智能技术为各行各业提供了更高效、便捷的解决方案。 食堂作为人们日常生活中不可或缺的一部分&#xff0c;也迎来了智能化的时代。智慧收银系统不仅提高了食堂的运营效率&#xff0c;还…

【算法Hot100系列】删除链表的倒数第 N 个结点

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

探讨二维半导体的概念、应用前景及其与传统半导体的差异

当探讨二维半导体时&#xff0c;我们置身于科技革新的前沿。这种材料以其纳米级薄度和独特电学性质区别于传统半导体&#xff0c;引发了科学界的广泛兴趣。本文将深入探讨二维半导体的概念、应用前景及其与传统半导体的差异。 什么是二维半导体&#xff1f; 二维半导体是由单…

分享4个文件自动备份方法,持续保护重要数据安全!

​如何执行文件自动备份任务&#xff1f;随着网络科技日新月异的高速发展&#xff0c;电脑和手机等电子设备在我们的日常工作生活中扮演着越来越重要的角色&#xff0c;使用频率逐渐增加&#xff0c;慢慢地也就离不开它了&#xff0c;从而导致积累在电脑中的重要数据量也在不断…

HackTheBox-Machines--Broker

文章目录 1 端口扫描2 测试思路3 漏洞探测4 CVE-2023-46604漏洞利用5.权限提升 Broker 测试过程 1 端口扫描 nmap -sC -sV 10.129.41.282 测试思路 目标开启了22、80、61616端口&#xff0c;在服务器开启了非web及一些需要账号密码进行登录的端口时&#xff0c;我们的入手点从这…

测试用例设计方法六脉神剑——第五剑:化气为型,场景用例破云

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

08‐Mysql全局优化与Mysql 8.0新特详解

文章目录 Mysql全局优化总结配置文件my.ini或my.cnf的全局参数最大连接数允许用户连接的最大数量MySQL能够暂存的连接数量JDBC连接空闲等待时长client连接空闲等待时长innodb线程并发数innodb存储引擎buffer pool缓存大小行锁锁定时间redo log写入策略binlog写入磁盘机制排序线…

22.JSP技术

JSP起源 在很多动态网页中&#xff0c;绝大部分内容都是固定不变的&#xff0c;只有局部内容需要动态产生和改变。如果使用Servlet程序来输出只有局部内容需要动态改变的网页&#xff0c;其中所有的静态内容也需要程序员用Java程序代码产生&#xff0c;整个Servlet程序的代码将…