markdown-to-jsxで画像にキャプションをつける
このブログはContentfulでmarkdownを書いて、Next.js側でmarkdown-to-jsを使って変換を行っている。
これまで画像の記法は ![alt](url)
を使っていたが、 ![alt](url "title")
と指定すると title属性も指定できる。
そこでmarkdown-to-jsのoverridesを使ってtitleが指定されている場合はfigcaptionでキャプションを付与するようにした。
import Markdown from 'markdown-to-jsx'
import React from 'react'
type Props = {
content: string
}
type CustomImageProps = {
src: string
title?: string
alt?: string
}
const CustomImage = ({ src, title, alt }: CustomImageProps) => {
if (title) {
return (
<figure>
<img src={src} title={title} alt={alt} />
<figcaption className="text-center">{title}</figcaption>
</figure>
)
}
return <img src={src} title={title} alt={alt} />
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const CustomParagraph = (props: any) => {
return React.Children.toArray(props.children).some((child) => typeof child === 'string') ? (
<p {...props} />
) : (
<div {...props} />
)
}
export const PostContent = ({ content }: Props) => {
return (
<div className="max-w-2xl mx-auto">
<Markdown
className="prose dark:prose-dark"
options={{
overrides: {
img: {
component: CustomImage,
},
p: {
component: CustomParagraph,
},
},
}}
>
{content}
</Markdown>
</div>
)
}
imgタグのみoverrideしただけだとconsoleに以下のWarningが出てしまった。
Warning: validateDOMNesting(...): <figure> cannot appear as a descendant of <p>.
そこで↓のissueにあるようにpタグもoverrideするように対応した。
これでmarkdownで画像キャプションが使えるようになった。