Next.js - MDXとシンタックスハイライト
1. MDX
MDX とは Markdown 内に jsx を記述できたり、コンポーネントを import できたりするので Markdown 形式 でより柔軟な対応ができます。よく利用するものなどをまとめておくと便利だと思います。ファイル形式は.md
ではなく.mdx
になります。
まず、Next.js で MDX を使用するために下記をインストールします。
npm install @next/mdx @mdx-js/loader
次にnext.config.js
というファイルをpackage.json
と同じ階層に作成して下記を記述すれば MDX を使用できるようになります。
const withMDX = require("@next/mdx")({
extension: /\.mdx?$/,
})
module.exports = withMDX({
pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"],
})
使用できるようになったか確認するために.mdx
ファイルを作成してその中に下記を記述して背景トマト色の<h3>
が表示されれば ok です。
<div style={{ padding: "20px", backgroundColor: "tomato" }}>
<h3>This is JSX</h3>
</div>
2. コードハイライト
コードハイライトする方法は色々あると思いますが、ここでは MDX でコードハイライト使用する方法です。MDX の公式サイトに書いてある方法をそのまま試しています。まずprism-react-renderer
をインストールします。
npm install prism-react-renderer
次にcodeblock.js
というファイルをcomponents
フォルダ内に作成し、下記を記述します。import theme
でコードハイライトのテーマを設定できるので、prism-react-renderer に入っているテーマから選びます。ここではgithub
を選んでいます。
//codeblock.js
import Highlight, { defaultProps } from "prism-react-renderer"
import theme from "prism-react-renderer/themes/github" //テーマを選択
export default function Code({ children, className }) {
const language = className.replace(/language-/, "")
return (
<Highlight
{...defaultProps}
code={children}
language={language}
theme={theme}
>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<pre
className={className}
style={{ ...style, padding: "20px", overflow: "auto" }}
>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token, key })} />
))}
</div>
))}
</pre>
)}
</Highlight>
)
}
上記で作成したcodeblock.js
を反映させるために_app.js
に下記を記述すれば完了です。
//_app.js
import { MDXProvider } from "@mdx-js/react"
import CodeBlock from "../components/codeblock"
const components = {
code: CodeBlock,
}
export default function App({ Component, pageProps }) {
return (
<MDXProvider components={components}>
<Component {...pageProps} />
</MDXProvider>
)
}
Next.js | MDX
next.js/examples/with-mdx at canary · vercel/next.js · GitHub