Blog StarterにZenn Markdownを組み込む

記事制作日:
web開発
目標
Blog Starterを使ってZenn Markdownが使える個人ブログを作成する
インストール
node.jsのインストール
node.jsのインストラーに従うだけ
blog-starterの追加
設置したいフォルダーを作成して、そのフォルダーに移動してから以下のコマンドを実行する
今回使用したlatestのバージョンは15.0.2
npx create-next-app@latest --example blog-starter .
Docker設定
Docker Desktopのインストール
Docker Desktopのインストーラーに従うだけ
Dockerfileの作成
Dockerfile
# Node.js 22がLTSなので、ベースイメージに指定
FROM node:22
# アプリケーション用の作業ディレクトリを作成
WORKDIR /app
# 依存関係をインストール
COPY package.json package-lock.json ./
RUN npm install
# ソースコードをコンテナ内にコピー
COPY . .
# 開発用サーバーを起動するポートを公開
EXPOSE 3000
# Next.js 開発サーバーをデフォルトで起動
CMD ["npm", "run", "dev"]
docker-compose.ymlの作成
docker-compose.yml
version: "3.8"
services:
blog:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
stdin_open: true
tty: true
.dockerignoreの作成
.dockerignore
node_modules
npm-debug.log
.dockerignore
dockerのビルド、起動
docker compose build
docker compose up
起動確認
にアクセスして、サンプルページが表示されれば無事に起動している
Zenn Markdown, CSSの導入
パッケージの追加
2024/12/30現在の最新バージョンは0.1.158だったので、package.jsonに追加
package.json
"dependencies": {
...
+ "zenn-content-css": "^0.1.158",
+ "zenn-embed-elements": "^0.1.158",
+ "zenn-markdown-html": "^0.1.158"
}
package.jsonを変更したので、一度ビルドする
docker compose build
Zenn Markdown, CSS対応のためのコードの変更
markdownをhtmlに変換する関数をzenn-markdown-htmlに変更
src/lib/markdownToHtml.ts
- import { remark } from 'remark'
- import html from 'remark-html'
+ import m2h from "zenn-markdown-html";
export default async function markdownToHtml(markdown: string) {
- const result = await remark().use(html).process(markdown)
- return result.toString()
+ return m2h(markdown)
}
zenn cssを読み込むように追加
src/app/layout.tsx
+ import 'zenn-content-css'
class名にzenn cssが動くようにzncを追加
src/app/_components/post-body.tsx
- <div className="max-w-2xl mx-auto">
+ <div className="max-w-2xl mx-auto znc">
Next.js 13からapp routerでは、サーバーコンポーネントでuseEffectを使えなくなった。
なので、クライアントコンポーネントとして切り分けてインポートする必要がある。
クライアントコンポーネントとしてsrc/app/_components/zenn-embed.tsxを作成する。
src/app/_components/zenn-embed.tsx
"use client";
import 'zenn-content-css';
import { useEffect } from "react";
export default function ZennEmbed(props: { html: string }) {
useEffect(() => {
import('zenn-embed-elements');
}, []);
return (
<div
className="znc"
dangerouslySetInnerHTML={{
__html: props.html,
}}
/>
);
}
ZennEmbedを使うために記事のページを変更する。
src/app/posts/[slug]/page.tsx
- import markdownToHtml from "@/lib/markdownToHtml";
+ import markdownToHtml from "zenn-markdown-html";
+ import ZennEmbed from "@/app/_components/zenn-embed";
...
- const content = await markdownToHtml(post.content || '')
+ const content = await markdownToHtml(post.content || '', {
+ embedOrigin: "https://embed.zenn.studio",
+ })
return (
<main>
<Container>
<Header />
+ <script src="https://embed.zenn.studio/js/listen-embed-event.js"></script>
<article className="mb-16">
...
- <PostBody content={content} />
+ <ZennEmbed html={content} />
</article>
</Container>
</main>
);
}
...
以上でblog-starterのpostでZenn Markdownが使えるようになる。
良い個人ブログライフを!
参考記事
Zenn Editor - GitHub
エンジニアなら自分でブログを作れ!③Markdownのカスタマイズ編
Next.js × microCMSでZennのマークダウンを表示するブログの作り方
Pages RouterからApp Routerへ移行した話 Next.js v13