Next.jsで作ったブログにStyleを適用していく
TL;DR
前回の記事で、markdown をうまくレンダリングできるようになったので、次は Style を適用していく。適用すべき対象は、最初の記事に書いたように、
- material-ui
- Prism.jsでのcode syntax
- amp-mathmlによる数式
- Github markdown css
である。AMP対応するには鬼門である。
Styleの適用
Prism.js && Github markdown css
prism.js公式サイトからcssをダウンロードしておく。github-markdown-cssからダウンロードする。github-markdown-cssは自動生成なので!importantとかが使われていてAMPに対応できないのでそのへんは除いてしまう。
Next.js 12になって、_document.jsでcssをロードすると怒られるようになってしまった。
仕方ないので、現状はcssをjsのstringとして保存しておいて、componentでimportし、sytled-jsxで表現している。
css.js
上のようなファイルを作成しておき
component.jsx
componentで読み込んで、そのままsytled-jsxに突っ込むことで、一応対応できている。
2021/07/01改稿 Next.js v11
webpack5を使っているとasset modulesを使うことでraw-loaderの機能が実装できる。まずはnext.config.jsに設定を書く。フルAMPなので、cssをimportすることは想定していない。
next.config.js
これでcssファイルをraw-loaderのように読み込める。
_document.js
2020/9/7 raw-loaderを使った実装
そのあと、raw-loaderを使ってcssを_app.tsxでimportして、直接埋め込む。できるならMarkdownのページだけで読み込みたいが...
ちょっとmaterial-ui成分も入ってしまっているが、_document.jsは以下の感じ。
_document.js
custom loaderでrefactorを使ってcodeをTokenに落とす作業をしておけばAMPでもコードがハイライトされる。順番の関係か、prismjsはダーク系のテーマにしたのに黒くならなかったので、github-markdown-css側で背景を黒にしておいた。
example
amp-mathml
KatexはAMPに対応できない。
そこで、まず、remark-mathを使って、mathとinlineMathのノードに変換する。その後、custom loaderを使って、type === "math"とtype === "inlineMath"に対応するamp-mathmlを埋め込む。インラインの数式はparagraphのchildrenなので注意が必要。
example
インライン数式
普通の数式
material-ui
2021/09/23
Material-UIのversionが上がったので、色々設定が必要になった。Emotionベースなので、AMP対応する場合は注意が必要。@emotion/serverのextractCriticalToChunksを使うのが重要らしい(参考)。
というのは、サーバーサイドレンダリングをnext.jsでするときに、CSSの読み込みがリセットされてしまうことがあるらしい(参考)。実際に自分の画面でも崩れていて、結構時間を溶かした。
幸いなことに、material-uiの公式がテンプレート例を作成してくれている(javascript, typescript)。これを参考にしながら_app.tsxと_document.tsxを書き換えておく。あとnext.jsのリンクとmaterial-uiのリンクもclassNameの問題とかでうまく行かないことがあるので、Linkコンポーネントを作っておく。
!importantを使用しているコンポーネントは使用できないので注意が必要になる。
感想
スタイルの適用はこんな感じ。しかし、material-uiは結構がっつりcssっぽいものを触らないとだめで結構難しい。Bootstrapはだいたいよしなにやってくれていたので、css力が本当に無い。