Web3 メディアをWordPressからmicroCMSに移行した時の話 〜Web3 × microCMSの勧め〜

microCMSをフル活用してWeb3メディアを立ち上げた話の記事です。

## はじめに

前職にて、Web3メディアを運営していましたが、WordPressでの運用に限界を感じ、microCMS + Next.jsへ移行しました。
（Web3事業部の縮小に伴い、残念ながら当該メディアはクローズ済みです）

- [国内最大級のNFT メディア「NFT NOW」がリニューアル。microCMSを導入し、Web3メディアとして国内初となるJAMStack化事例に
](https://prtimes.jp/main/html/rd/p/000000027.000029349.html)

しかし、当時microCMSには大いに助けられました。

国内のWeb3・仮想通貨・ブロックチェーン関連メディアでは、サイト構築にWordPressが主流となっていますが、技術的特性を考えると、むしろJAMStackの方が適していると考えられます。
microCMSはWeb3メディアと親和性の高いツールであり、もっと採用が増えるべきだと思っています。


本記事では、Web3企業におけるmicroCMSの活用促進を目指して、『Web3とmicroCMSの親和性』や『WordPressからmicroCMSへの移行がもたらすメリット』について解説します。

## 自己紹介

こんにちは、アームサード 株式会社 CEO のへいきょと申します。
元々は SaaS や SNS, マッチングサイト、オウンドメディアなどあらゆる分野で新規事業を立ち上げてきたのですが、最終的に Web3 業界に辿り着きました。
PdM/PjMとして国内外で多くの Web3 プロダクトに従事し、CTO や VPoE も複数社で経験しました。

今年からアームサード株式会社を創業し、グローバルの L1/L2 チェーンやプロトコルに対して開発支援や事業開発支援を提供しています。

## この記事はこんな人におすすめ

- Web3メディアの立ち上げを検討している事業責任者
- Web3 x CMSのユースケースに興味がある方
- microCMSとWeb3が好きなエンジニア
- オウンドメディアの技術選定に悩んでいるPM


## 作ったもの

JAMStackなWeb3メディアを構築し、さらにWeb3特有の機能をアクセントとして追加しました。

- [国内最大級のNFTメディア「WEB3NOW」が、NFTオンチェーンデータの自動ピックアップ機能を実装
](https://prtimes.jp/main/html/rd/p/000000046.000029349.html)

### 技術スタック
| 項目 | 技術スタック |
|--------|------------|
| 言語 | TypeScript |
| フレームワーク | Next.js(React.js) |
| Headless CMS | microCMS |
| ホスティングサーバー | Vercel |
| CSSライブラリ | Chakra UI |
| Ethereum JavaScript API | Ethers.js |
| Token API | Moralis |

### 主要な機能例

- 記事のページネーションやカテゴリーやタグによるフィルタリングなど
- サイト内検索機能
- ライター一覧表示（SNSなどに加えて、NFTマーケットプレイスのユーザーページへのリンクアイコンも）
- NFTオンチェーンデータの自動ピックアップ機能（コレクション名, OpenSea上の累計売上, 最低落札価格, NFTの総数, NFTの所有者総数, NFTコントラクトのデプロイ日など）

## microCMSとは

microCMSはAPIベースの日本製ヘッドレスCMSです。
コンテンツのためのサーバー管理は一切不要、サインアップするだけですぐに利用開始できます。
JAMStackアーキテクチャやNext.jsなどのモダンな技術スタックが前提となっており、リリース当初から国内のエンジニアから強く支持されてきました。
**Contenfulやghost, Netlify CMSなどHeadless CMSは片っ端から触ってきたのですが、国産プロダクトであることを差し引いてもmicroCMSは一番使いやすかった**です。

- [公式HP](https://microcms.io/)


## JAMStackとは

JAMStackは、JavaScript、API、Markupの頭文字を組み合わせたモダンなウェブ開発アーキテクチャです。
特にオウンドメディア構築に相性が良い技術で、WordPressに代わる選択肢としてよく採用されています。
事前にビルドされた静的なHTMLファイルをCDNで配信し、必要に応じてJavaScriptでAPIを呼び出して動的なコンテンツを表示します。
従来のサーバーサイドレンダリングと異なり、ビルド時に静的ファイルを生成するため、高速な表示とセキュリティの向上が特徴です。代表的なフレームワークにはGatsby、Next.js、Nuxt.jsなどがあります。
人気のホスティングサービスにはNetlify、Vercel、GitHub Pagesなどがあり、デプロイが簡単で運用コストを抑えられます。

- [Jamstackとは何か？非エンジニアにもわかりやすく基本を解説！](https://blog.microcms.io/jamstack-introduction/)

## microCMSの運営会社について

株式会社microCMSは日本で著名なエンジニア・デザイナーが中心となって立ち上げたスタートアップです（昔は違う社名だった気がします）。

特にNext.jsやNuxt.jsなどのモダンな技術スタックにおいて影響力のあるメンバーが在籍していたことから、microCMSはローンチ当初から日本のエンジニア間で有名でした。

エンジニアドリブンな組織風土だからか、機能選定や開発者向けのグロースハック施策などが実に見事で、（勝手に）よく参考にさせていただいていました。

- [株式会社microCMS](https://microcms.co.jp/)

:::note
2024年5月、microCMSはエイチームに15億円でM&Aされました。
おめでとうございます🥳
:::

## WordPressからmicroCMSへの移行するメリット

**元々WordPressを使用していたのですが、「サイト開発とコンテンツ管理が厳密に分離されていないこと」** に伴う不便に悩まされていました。

そこで思い切ってサイトリニューアルを行うことで、JAMStackのメリットを享受できました。

1. **サイト開発とコンテンツ管理の完全な分離による開発効率化**
2. **純粋な静的サイト化によるサイトパフォーマンスの向上**
3. **ライター管理コストの削減**
4. **microCMSのエディタとショートコード実装による記事執筆の効率化**

元々は特に開発効率化を企図していたのですが、想像していた以上に**開発記事の企画から公開までの工数を大幅に削減することに成功**しました。
（たまに自分でも記事を執筆していたのですが、WordPressに比べて本当に書きやすくなりました。ライターの管理コストも下がりました）

## WordPressからmicroCMS移行のフロー・注意点

### サイト構築

Next.jsやNuxt.jsなど任意のフレームワークでサイトを構築する必要があります。
しかし**フルスクラッチでコーディングする必要はなく、主要フレームワークごとに豊富なテンプレートが用意**されています。
社内のエンジニアが極めて優秀だったのもありますが、スムーズに開発することができました。

- [microCMS テンプレート集](https://templates.microcms.io/)

### コンテンツの移行

コンテンツの移行（記事のマイグレーション）自体はそう難しくありませんでした。
当時は記事数が少なかったのでWordPressから全記事をマークダウンファイルとしてエクスポートして、手動でmicroCMSに登録しました。
不要な記事の廃止も行ったのでトータル40記事程度でした。
プログラマブルに移行する方法もありますが、記事の母数的に手動の方がむしろお手軽でした。
記事数が多かったら他の手段を選択する必要があったと思います。

### 記事のSEO順位継承

しかし**ボトルネックになったのは記事のSEO順位継承**です。
実は、サイトリニューアルのタイミングでホスティングドメインも独自ドメインからサブドメインへ変更を行いました。
後者のDomain Authorityの方が高く、今後さらに強化される見込みだったためです（そのドメインで複数のWeb3プロダクトをホスティングしていて被リンク獲得が圧倒的に多かった）。

当時はSEO上位の仮想通貨メディアの顔ぶれが変わった時期でもあり、その背景が独自ドメインに対するサブドメイン・サブディレクトリの優位性でした。

うろ覚えですが下記を行ったと思います。
- 移行前/後で記事のslugを同一のものにして、1:1で対応させる（元々WordPress時代からきちんと意味のあるslugを指定していました）
- 従来のホスティングドメインから移行後のサブドメイン対して、slugごとに全記事をRedirectさせスクリプトファイルをWordPress上に設置する（これでSEO順位を引き継げる）

具体的にどのようなスクリプトを書いたかは覚えていませんが、数行程度のシンプルなもので済みました。

### microCMSのショートコード実装

WordPressエディタで使っていたいくつかの機能を再現するために、microCMSのショートコードを実装する必要がありました。
といっても数は限られているので、これもボトルネックではありませんでした。

## なぜ Web3 メディアと microcms の相性が良いのか

web3メディアには下記のような性質があり、microCMSと親和性が高いです。

1. **記事更新頻度の高さ**（特にリライト記事の運用）
2. **柔軟な開発体制**（求められる開発要件が重い）
3. **扱うデータとの親和性（オンチェーン上のIDだけでメディアのコンテンツを充実させることができる）**

### 記事更新頻度の高さ

**Web3メディアにおいて、いくつかの重要な記事はリライトを行い続ける必要**があります。
例えば下記のようなクエリの記事を考えてみます。
これらは極めてSEO難易度が高いクエリであるため、記事のリライトを続けて情報鮮度を保たないと、SEO順位が下がりやすくなってしまいます。
（※もちろん実際にはこれらのクエリでSEOを取るのは至難の業ですが、わかりやすさのため）
- 「仮想通貨　おすすめ」
- 「仮想通貨取引所　おすすめ」
- 「Ethereum 買い方」

microCMSのようなHeadless CMSなら、記事の更新とバージョン管理がしやすくなります。

### 柔軟な開発体制

**Web3メディアでは、求められる開発要件が重い**傾向にあります。
例えば下記などがよくある要求です。

- 主要仮想通貨の価格やレートをリアルタイムで表示する
- リッチなサイトデザインでWeb3らしさを表現する
- NFTの取引高ランキングを表示する

これらをWordPressで実装するのは骨が折れますが、JSフレームワークならなんとなく実装イメージが湧くのではないでしょうか。
サイト開発とコンテンツ管理を完全に分離できるJAMStackは開発効率が良く、機能要件に柔軟に応えることができます。
また、**そもそもWeb3企業にはWordPressの経験が豊富なエンジニアが少ないので、技術スタックを統一できる**というメリットもあります。

### 扱うデータとの親和性

microCMS上で扱うデータには、大別して二つの性質があります。
1. **頻繁に更新する**（記事の本文など）
2. **最初に登録したら更新しない**（記事のSlugやライターの氏名など）

後者として、microCMS上で「オンチェーン上のID」を扱うと便利です。

Web3に馴染みがない人には想像しづらいと思うのですが、**基本的にオンチェーンデータ（ブロックチェーン上のデータ）はすべてパブリックに公開されており、誰でも自由に取得できます**。
**つまり、目当てのデータもKeyさえあれば簡単に取得・表示できます**。
例えば、Wallet Addressとは「メールアドレスと銀行の口座番号とSNSのユーザーIDが一緒になったようなもの」です。
Wallet Addressは「Unique」（重複がない）かつ「Immutable」（不変）な文字列であり、オンチェーンデータと紐づくUnique IDとして機能します。

つまり、Wallet Addressがわかるだけで、そのユーザーのオンチェーン上のアクティビティや資産状況がすべてわかります。

そしてこれは仮想通貨やNFT、スマートコントラクト（オンチェーン上のプログラム）にも同じことが言えます。
それぞれにContract AddressというUnique IDが割り振られているため、関連するオンチェーンデータを自由に取得できます。

また、仮想通貨には仮想通貨取引所のチャートなど、便利なサードパーティのWeb APIもたくさん提供されています。

**これらをmicroCMS上に追加しておき、サイト側に渡すことで、様々な処理をページやコンポーネントファイル上で実行**できます。

例えばmicroCMS上でライターの情報にWallet Addressを追加することで下記が可能です:
- 記事の執筆者のNFTマーケットプレイスのユーザーページへのリンクを自動生成できる。つまり、どのようなNFTを所有しているのかがわかる
- オンチェーン上の信頼性をオンチェーンスコアとして表示する（Gitcoin Passportなどを使用）

また、NFTのToken Addressを登録することで下記のような機能も可能です:
- そのNFTの累計の取引高やFloor Priceをリアルタイムで表示する
- 主要なNFTマーケットプレイスでそのNFTを購入するための動線を設置

## おわりに

本記事では、microCMSを使ったWeb3メディア構築について書きました。
（microCMSのスキーマ例やコードサンプルなども書けば良かったかも？要望あれば追記します）

WordPressからmicroCMSに移行するメリットやフロー、microCMS x Web3で実現することなどをお伝えできれば幸いです。

## APPENDIX: microCMSに興味を持ったエンジニアへの参考資料

開発を始められるように、いくつか資料を紹介します。

### 『Next.js＋ヘッドレスCMSではじめる！ かんたんモダンWebサイト制作入門 高速で、安全で、運用しやすいサイトのつくりかた』
microCMS創業者自ら筆を取ったJAMStack本が発売されました。
Next.jsとmicroCMSによるブログ構築をハンズオンで進めることができるため、こちらが最もわかりやすいと思います。
- [『Next.js＋ヘッドレスCMSではじめる！ かんたんモダンWebサイト制作入門 高速で、安全で、運用しやすいサイトのつくりかた』](https://amzn.to/4eTUM2d)

### microcms-blog（GitHubリポジトリ）
また、microCMS社のブログのGitHubリポジトリも公開されています。Apache License 2.0なので、自由に使用することが可能です。
Forkしてそのまま会社ブログに使用しても良いでしょう。
ただし、Nuxt.js製なので、Vue.jsに慣れていない人は使用するのは避けた方が良いでしょう。
（コードをそのまま使わなくても、APIスキーマなどとても参考になります）

https://github.com/microcmsio/microcms-blog

### nextjs-simple-blog-template（GitHubリポジトリ）

Next.jsの公式テンプレートです（他にもいくつかあります）。
https://github.com/microcmsio/nextjs-simple-blog-template

## APPENDIX: web3 × microCMS のAPIスキーマ例

基本的にはmicroCMS blogのAPIスキーマを踏襲していますが、Web3要素を取り入れた例です。

### 記事
- endpoint: article
- type: リスト形式

| フィールド ID | 表示名     | 種類                        |
| ------------- | ---------- | --------------------------- |
| title         | タイトル   | テキストフィールド          |
| category      | カテゴリー | コンテンツ参照 - カテゴリー |
| tag           | タグ       | 複数コンテンツ参照 - タグ   |
| body          | 本文       | リッチエディタ              |
| description   | 概要       | テキストフィールド          |
| thumbnail     | OGP 画像   | 画像                        |
| author        | 著者       | コンテンツ参照 - 著者       |
| chain        | 著者       | セレクトフィールド       |
| contractAddress        | コントラクトアドレス      | テキストフィールド      |
| chain        | 著者       | コンテンツ参照 - 著者       |
| collectionSlug        | openseaコレクションslug      | テキストフィールド      |


### 著者
- endpoint: authors  
- type: リスト形式

| フィールドID | 表示名 | 種類 |
| ------------- | ------------- | ----- |
| name | 名前 | テキストフィールド |
| bio | 自己紹介 | テキストエリア |
| avatar | 画像 | 画像 |
| twitterID | Twitter ID | テキストフィールド |
| walletAddress | Wallet Address | テキストフィールド |