Closed5
Next.jsでmdxを使ってみる
準備
# デフォのままだとjsなので、ts対応したexampleから始める
$ npx create-next-app --example with-typescript mdx-sample
$ cd mdx-sample
# mdx追加
$ yarn add yarn add @next/mdx @mdx-js/loader
参考リンク
next.config.js修正
おそらく無いので作るところから。
$touch next.config.js
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/
});
module.exports = withMDX({
pageExtensions: ['ts', 'tsx', 'md', 'mdx']
});
サンプル追加
# pages配下にmdxファイルを追加
$ touch pages/hello.mdx
hello.mdx
# sample
ここから↓がjsx.
<article>
<h1>Hello World!</h1>
<div style={{backgroundColor: 'red', fontSize: '200%'}}>
sample text.
</div>
</article>
component読みこむ
header component作成
お試しのコンポーネントを作る。
Header.tsx
import React from 'react';
import style from './Header.module.css';
interface Props {
heading: string,
color?: 'red' | 'blue'
}
export const HeaderComponent: React.FC<Props> = ({heading, color}) => {
if (!color) {
return <h1 className={style.header}>{heading}</h1>;
}
switch(color) {
case 'red':
return <h1 className={`${style.header} ${style['header--red']}`}>{heading}</h1>;
case 'blue':
return <h1 className={`${style.header} ${style['header--blue']}`}>{heading}</h1>;
}
}
Header.module.css
.header {
font-size: 28px;
}
.header--red {
color: red;
}
.header--blue {
color: blue;
}
mdx修正
hello.mdx
import {HeaderComponent} from '../components/header/Header.tsx';
# sample
ここから↓がjsx.
<article>
<HeaderComponent heading="Hello World!"/>
<div style={{backgroundColor: 'red', fontSize: '200%'}}>
sample text.
</div>
</article>
<article>
<HeaderComponent heading="Hello World!" color="red"/>
<div style={{backgroundColor: 'red', fontSize: '200%'}}>
red heading.
</div>
</article>
<article>
<HeaderComponent heading="Hello World!" color="blue"/>
<div style={{backgroundColor: 'red', fontSize: '200%'}}>
blue heading.
</div>
</article>
コードブロック作ってみる
mdのコードブロックでシンタックスハイライトが効かないっぽかったので自作。
絶対うまいやり方がある気がする。
ライブラリ追加
$ yarn add prism-react-renderer
コンポーネント作成
Codeblock.tsx
import React from 'react';
import Highlight, {defaultProps, Language} from 'prism-react-renderer';
export const CodeBlockComponent: React.FC<{code: string, language: Language}> = ({code, language}) => {
return (
<Highlight {...defaultProps} code={code} language={language}>
{({className, style, tokens, getLineProps, getTokenProps}) => (
<pre className={className} style={{...style, padding: '20px'}}>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({line, key: i})}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({token, key})} />
))}
</div>
))}
</pre>
)}
</Highlight>
)
};
mdx修正
hello.mdx
import {HeaderComponent} from '../components/header/Header.tsx';
import {CodeBlockComponent} from '../components/codeblock/CodeBlock.tsx';
# sample
ここから↓がjsx.
<article>
<HeaderComponent heading="Hello World!"/>
<div style={{backgroundColor: 'red', fontSize: '200%'}}>
sample text.
</div>
</article>
<article>
<HeaderComponent heading="Hello World!" color="red"/>
<div style={{backgroundColor: 'red', fontSize: '200%'}}>
red heading.
</div>
</article>
<article>
<HeaderComponent heading="Hello World!" color="blue"/>
<div style={{backgroundColor: 'red', fontSize: '200%'}}>
blue heading.
</div>
</article>
<CodeBlockComponent
code={`
const hoge = 'hoge';
console.log(hoge);
`}
language="javascript"
/>
↓はハイライトされない
```js
const hoge = 'hoge';
console.log(hoge);
参考リンク
このスクラップは2020/12/29にクローズされました