こんにちは、エンジニアのオオバです。
MDXから出力したHTMLの加工ができない!!
そういう悩みありませんか?
目次が作りたくて、
以下のように出力したい場合があります。
<h2>あああああああああ</h2>
<h3>いいいいいいいいい</h3>
↓
<h2 id = "あああああああああ">あああああああああ</h2>
<h3 id = "いいいいいいいいい">いいいいいいいいい</h3>
本記事ではMDXのカンタンな
整形方法をわかりやすく解説していきます。
→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら
本記事で解決すること
- 追加ライブラリなしでMDXにidを生成する
- ※前提 : next/mdxを使用
- next.config.js変更不要
MDXProviderにMDX整形ルールを渡すだけ
最初に結論です。
MDXProvider
にカスタムしたコンポーネントを渡すことで
MarkDownからMDXへの整形をカスタマイズできます。
- Appコンポーネント
- MDX整形ルールの定義
手順1.Appコンポーネントの修正
_app.jsx(.tsx)のコンポーネントの修正内容です。
引数のpagePropsをMDXProvider
で囲みます。
具体的には以下のコードです。
💻ソースコード : _app.jsxの抜粋
<MDXProvider components={mdComponents}>
<Component { ...pageProps } />
</MDXProvider>
このままではmdComponents
が
存在しないエラーが出てしまいますので、
mdComponents
について解説します。
手順2.MDX整形ルールの定義
ポイントはココ{mdComponents}
です。
htmlタグ要素に対して、整形ルールを
オブジェクト型で定義します。
具体的には以下のコードです。
💻ソースコード : _app.jsxの抜粋
const mdComponents = {
h1: (props) => { return (<h1 id={props.children}>{props.children}</h1>)},
h2: (props) => { return (<h2 id={props.children}>{props.children}</h2>)},
h3: (props) => { return (<h3 id={props.children}>{props.children}</h3>)},
}
h1
〜h3
のタグの時の加工処理を記述してます。
### hogehoge
<h3 id="hogehoge">hogehoge</h3>
と整形されます。
まとめ
本記事では追加ライブラリなしで、
MDXのHTMLタグをカスタマイズしてみました。
手順をまとめると以下の3つです。
- 整形ルールを作成
- MDXProviderで囲む
- MDXProviderに整形ルールを渡す
コード全体はコチラ
💻ソースコード : _app.jsxの抜粋
import { MDXProvider } from "@mdx-js/react"
// ~~~ 省略 ~~~
// MDX整形ルール
const mdComponents = {
h1: (props) => { return (<h1 id={props.children}>{props.children}</h1>)},
h2: (props) => { return (<h2 id={props.children}>{props.children}</h2>)},
h3: (props) => { return (<h3 id={props.children}>{props.children}</h3>)},
}
const MyApp = ({ Component, pageProps }) => {
// ~~~ 省略 ~~~
return (
<>
// ~~~ 省略 ~~~
<MDXProvider components={mdComponents}>
<Component { ...pageProps } />
</MDXProvider>
// ~~~ 省略 ~~~
</>
)
}
export default MyApp
ERR_REQUIRE_ESMでremark-slugは使えなかった
最初remark-slugというプラグインを検討しましたが、
ERR_REQUIRE_ESMというエラーで断念。
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:
以下のようにnext.config.jsに
設定するだけでは済みませんでした。
💻ソースコード : next.config.jsの抜粋
const withMDX = require('@next/mdx')({
extension: /\.(md|mdx)?$/,
options: {
remarkPlugins: [require('remark-slug')],
},
})
const nextConfig = {
// ~~~省略~~~
}
module.exports = withMDX(nextConfig)
remark-slugを使う方法は、
キーワード "Next.js 目次作成" で検索すると
ヒットします。
執筆時点ではうまく動かなかったことを共有しておきます。
この記事が気に入ったらフォローしよう
- Next.js v11.1.2
- React v17.0.2
- next/mdx v10.0.9
- mdx-js/loader v1.6.22