在NextJS中为rehype代码块添加复制按钮
创建于:发布于:文集:随笔 我的博客中使用了rehype-pretty-code
加shiki
来美化代码块,rehype-pretty-code提供了一个shiki的transformer来自动给代码块加上复制按钮,它会生成这样的代码:
但是在NextJS中目前想要不做额外处理地使用它,只能使用React Server Components,将生成的HTML文本传入dangerouslySetInnerHTML
:
但在某些场景下没法直接用服务端组件,下面给出对应的解决办法。
如果要结合MDX使用,MDX会把生成的button
当成React组件处理,而React组件的onClick
属性需要的是函数对象而不是字符串,为了防止XSS这类安全问题又不能将字符串直接eval成函数,这里就会报错。
解决办法是通过MDX自定义components的方式,先自定义一个复制按钮组件:
这个组件不是服务端组件,所以在开头第一行要加"use client"
,className
可以复用一下,子组件切换复用有点麻烦,干脆直接自定义的图标了。
下一步就是通过MDX的API替换生成的button:
这样就可以实现复制代码按钮了。
直接使用我的@docube/org通常来说是没有问题的,但是由于我的文章页面的结构大致是这样的:
React的dangerouslySetInnerHTML
不能直接作用到Fragment
上,也就是必须要给content加个父元素,我个人有点受不了……
为了能不加额外的父元素,我使用了html-react-parser
这个库,它又带来了新的问题,也就是为了安全,它会直接忽略onclick
属性,导致只能渲染按钮却没有复制的功能。
解决办法如下: