August 31, 2019
gatsby-transformer-remarkで出力されるコンポーネントをカスタマイズする方法
こんにちは。mono(@mono7555e)です。
このブログがGatsbyJSで作られていること、gatsby-transformer-remarkを使ってMakrdownを読み込んでいることは以前にもご紹介しましたが、今回はそこで出力されるHTML(コンポーネント)をカスタマイズする方法をご紹介したいと思います。
かなり簡単で、ずばりrehype-reactを使うとやりたいことが出来ます。
既存コンポーネントを独自コンポーネントに置き換える
まずはh1
やp
などの既存コンポーネントを置き換える方法についてです。
私が実際に使っているものを例にするとこんな感じになります。
import rehypeReact from "rehype-react"
import { Box, Typography } from "@material-ui/core"
// 中略
export const renderAst = new rehypeReact({
createElement: React.createElement,
components: {
'h2': (props: TypographyProps) => {
return (
<Box mt={4} mb={2} py={2} px={3} bgcolor="primary.400" color="common.white">
<Typography variant="h6" component="h2" {...props}></Typography>
</Box>
)
},
'h3': (props: TypographyProps) => {
return (
<Box mt={4} mb={2} py={1} px={2} borderLeft={4} borderColor="primary.500">
<Typography variant="h6" component="h3" {...props}></Typography>
</Box>
)
},
'h4': (props: TypographyProps) => {
return (
<Box mt={4} mb={2} py={1} px={1} borderBottom={1} borderColor="primary.500">
<Typography variant="body1" component="h4" {...props}></Typography>
</Box>
)
},
'p': (props: TypographyProps) => {
return (
<Typography variant="body2" component="p" style={{ marginTop: `1rem`, marginBottom: `1rem`, lineHeight: 1.8 }} {...props}></Typography>
)
},
// などなど
},
}).Compiler
全体的にMaterial-UIを使っているので、そのコンポーネントに各既存コンポーネントを置き換えています。
あとは、GraphQLで取得するデータをhtml
からhtmlAst
に変更し、定義したrenderAst
を使うように書き換えます。
具体的には
<div dangerouslySetInnerHTML={{ __html: html }} />
を↓に置き換える感じです。
<div>{renderAst(htmlAst)}</div>
ここまで来ればあとは自由にカスタマイズ可能です。
独自コンポーネントを読み込む
前述の例では、既存コンポーネントを独自コンポーネントに置き換える方法でしたが、独自コンポーネントを追加することも出来ます。
まずは読み込みたいコンポーネントを作ります。
import React from 'react'
const Custom = () => {
return(
<div>
<p>独自コンポーネント</p>
</div>
)
}
export default Custom
Markdownファイルのコンポーネントを読み込みたい場所にタグを追加します。
↓コンポーネント読み込み↓
<custom></custom>
↑コンポーネント読み込み↑
※ちなみに<custom />
と書きたくなりますがこれだとダメでした
それが置き換えられるようにrehypeReact
を設定します。
import rehypeReact from "rehype-react"
import Custom from "../components/custom"
// 中略
export const renderAst = new rehypeReact({
createElement: React.createElement,
components: {
'custom': Custom,
},
}).Compiler
これで<custom></custom>
と書かれたところCustom
コンポーネントになって出力されるようになります。
まとめ
gatsby-transformer-remark
を使っている際にカスタマイズをしたい場合rehype-react
を使えば簡単なことであれば大体のことは出来ると思います。
もし、さらにより細かいカスタマイズを行いたい場合は今回のように置き換えるのではなくて、コンポーネント自体を読み込めるようになるMDXを使うと良さそうです。