microCMSブログのNext.js版を作成した
はじめに
microCMS 様が自社ブログのソースコードを github にあげてくださっています。
本家 microCMS 様のブログは Nuxt.js×Netlify という構成です。
最近は Next.js×Vercel という構成をよく見るため、せっかくなので勉強がてら Next.js×Vercel 構成のブログを頑張って作ってみました。
デモサイト →
ソースコード →
また私と同じ試みをされている方がいらっしゃいます。
こちらのソースコードでは、私の方では利用していないaspida や pathpida、useSWR等を使用されています。
他にも私のとは違った書き方・技術構成となっていますので、ぜひご参考になさってください。
microCMS とは
microCMS はクラウド型のヘッドレス CMS です。
コンテンツ管理のためのサーバ管理は一切不要で、サインアップするだけですぐにサービスを利用開始できます。
詳しくは、下記リンクをチェック
方針
デザイン、コンポーネント、コンテンツ、機能は microCMS ブログとほぼ同様のものにする。
技術構成
- Next.js (SSG + SSR)
- TypeScript
- CSS Modules
- microCMS (コンテンツ)
- Vercel (Hosting, API)
機能の比較
microCMS ブログと同じ機能にしようと頑張りましたが、すべての機能を作成しませんでした。
差分で赤くなっている項目は今回は含めていません。
記事一覧
カテゴリー別記事一覧
人気の記事一覧
最新の記事一覧
検索
パンくずリスト
記事詳細
目次
著者
SNSシェアボタン
下書きプレビュー
関連記事
サイトマップ
バナー
Google Analytics
RSS
- PWA
microCMS の API スキーマ設定
API スキーマ設定
ブログ
endpoint: blog
type: リスト形式
フィールド ID | 表示名 | 種類 |
---|---|---|
title | タイトル | テキストフィールド |
category | カテゴリー | コンテンツ参照 - カテゴリー |
toc_visible | 目次 | 真偽値 |
body | 本文 | リッチエディタ |
description | 概要 | テキストフィールド |
ogimage | OGP 画像 | 画像 |
writer | 著者 | コンテンツ参照 - 著者 |
partner | パートナー | コンテンツ参照 - パートナー |
related_blogs | 関連記事 | 複数コンテンツ参照 - ブログ |
著者
endpoint: authors
type: リスト形式
フィールド ID | 表示名 | 種類 |
---|---|---|
name | 名前 | テキストフィールド |
text | 自己紹介 | テキストエリア |
image | 画像 | 画像 |
カテゴリー
endpoint: categories
type: リスト形式
フィールド ID | 表示名 | 種類 |
---|---|---|
name | 名前 | テキストフィールド |
パートナー
endpoint: partners
type: リスト形式
フィールド ID | 表示名 | 種類 |
---|---|---|
company | 会社名 | テキストフィールド |
url | 会社 URL | テキストフィールド |
description | 説明文 | テキストエリア |
logo | ロゴ | 画像 |
人気の記事
endpoint: popular-articles
type: オブジェクト形式
フィールド ID | 表示名 | 種類 |
---|---|---|
articles | 人気の記事 | 複数コンテンツ参照 - ブログ |
バナー
endpoint: banner
type: オブジェクト形式
フィールド ID | 表示名 | 種類 |
---|---|---|
image | 画像 | 画像 |
url | リンク先 URL | テキストフィールド |
alt | 代替テキスト | テキストフィールド |
コンテンツ更新時の自動ビルド設定
SSG にしているので、再ビルドしないと最新のコンテンツが更新されません。
なので、microCMS のコンテンツ更新時に Vercel の自動ビルドされるようにします。
Vercel 側の設定
Settings タブ -> Git -> Deploy Hooks にHook Name
とデプロイ対象のGIt Branch Name
を入力する。
その後生成される URL をコピーする。
microCMS 側の設定
対象の API を選択し、「API 設定」に遷移。
WebHook -> カスタム通知 を選択。
Webhook の名前、上記でコピーした URL、通知タイミングを選択し、設定ボタンを押下。
下書きプレビューについて
下書き中のコンテンツの取得方法
microCMS ではコンテンツが下書き状態のとき、draftKey
が発行されます。
コンテンツ取得のリクエスト時にクエリパラメータにdraftKey
を付与することで下書き中のコンテンツを取得することができます。
プレビューー機能
microCMS にはプレビュー機能があり、「画面プレビュー」ボタンを押下した際の遷移先 URL を指定することができます。
API 設定 -> 画面プレビュー
実装方法
下書きコンテンツの取得の流れは以下のようになります。
- microCMS の管理画面から「画面プレビュー」を押下し、プレビュー画面を表示する。
- クライアント側が
コンテンツのid
とdraftKey
を受け取り、API へリクエスト。 - 取得データをレンダリング
プレビュー用ページの追加
まずはプレビュー用のページを用意します(/draft
)
プレビューページはビルド時ではなく URL からアクセスされたタイミングでクライアント側から API リクエストを行います。
また、クライアント側から直接 microCMS の API を叩くと APIKey が見えてしまうので、Next.js の API Routes を利用します。
const Draft = (props) => {
const router = useRouter();
const [data, setData] = useState<IDraftResponse>(null);
const [isLoading, setLoading] = useState<boolean>(true);
const fetcher = async () => {
const query = router.query;
const data = await axios.get(`${config.baseUrl}/api/draft?id=${id}&draftKey=${draftKey}`); // 下書き状態のコンテンツ取得
setData(data);
setLoading(false);
};
useEffect(() => {
// router.queryが最初のレンダリングでは取得できないため、
// 二回目のレンダリングからリクエストを送るようにする
if (router.isReady) {
fetcher();
}
}, [router.isReady]);
return (
// 省略
)
}
下書きコンテンツ取得用 API を作成
上記で述べたように API Routes を利用するので、/pages/api/draft.tsx
を作成します。
export default async (req: NextApiRequest, res: NextApiResponse) => {
const id = req.query.id;
const draftKey = req.query.draftKey;
if (!id || !draftKey) {
res.status(400).json({ error: `missing queryparamaeter` });
}
return axios
.get<IBlog>(
`https://${config.serviceId}.microcms.io/api/v1/blog/${id}?draftKey=${draftKey}&depth=2`,
{
headers: { 'X-MICROCMS-API-KEY': config.apiKey },
},
)
.then(({ data }) => {
// 目次の生成やHTMLへの変換もやってしまう
const toc = convertToToc(data.body);
const body = convertToHtml(data.body);
res.status(200).json({ blog: data, toc: toc, body: body });
})
};
プレビュー画面遷移用の URL を設定
API 設定 -> 画面プレビューを開き
「https://yourdomain.com/draft?id={CONTENT_ID}&draftKey={DRAFT_KEY}
」を設定する
追加していきたいこと
- PWA
最後に
間違ってる点や改善点が多々あると思いますが、ご活用いただければ幸いです。
Discussion
ご参考になる記事ありがとうございます。
Githubも確認させて頂いた上で、Googleアナリティクスの導入についてお聞きしたいことがあります。
上記の導入において、gtag.ts, _documents.tsx, next-env-d.tsの三箇所が主な変更点かなと思っております。
しかしネット上の様々な記事を拝見したところ、_app.tsxにPV数を測るイベントを導入していることが多いです。
wattanxさんの現状のコードでも無事にPV数の測定は可能となっていますでしょうか?
お手隙の際に、ご回答いただけたら幸いです。
ご報告ありがとうございます!
おっしゃる通り
_app.tsx
にPV数を測定するイベントを設定する必要がありました。(完全に忘れておりました...)
修正して反映しております。
Googleアナリティクスの導入での変更点は、
gtag.ts
,_document.tsx
,next-env-d.ts
,_app.tsx
になります。また、導入にあたり私が参考にしたのは下記の記事とNext.js公式のソースコードです。
wattanxさんご回答、参考記事まで追記ありがとうございます。
導入において、改めてお聞きしたことがあります。
pageViewメソッド発火時に、gtag.tsのwindow.gtag('config'~~~~~)は正常通りに実行されましたでしょうか?
原因は謎なのですが、私の実行環境ではwindow.gtag is not functionと怒られてしまって...
また、googleAnalyticsは最新のGA4(測定ID)、旧バージョンのユニバーサル(トラッキングID)どちらで設定していらっしゃいますでしょうか?
もしよろしければご回答いただけると幸いです。。
私はGA4のほうで設定してます!
もしかしたら下記の<script>タグがないとかですかね...
私のソースコード上で変な動きしているところがあれば、またお時間のあるときにgithubのissue投げちゃってください!