WordPress の自社ブログを Gatsby.js で静的サイトに移行した話 - コンテンツ検討編

WordPress の自社ブログを Gatsby.js で静的サイトに移行した話 - コンテンツ検討編

WordPress で運営していた自社ブログを Gatsby.js で静的サイトに移行した話の 2 記事目です。

WordPress から別システムへの移行を検討している方や Gatsby の導入を検討している方の参考になれば幸いです。

長くなりましたので何回かに分けてお送りしています。 前回(運用検討編) は、下記の内容まで検討を進めました。

  • Markdown をファイルで Git 管理する
  • GitHub の Pull Request でレビュー・承認する
  • GitHub の Pull Request のマージによってリリースする

今回は移行にあたって必要となる下記のような細かいところを検討しました。

  • ブログに必要なページと機能の検討
  • 運用ルールの検討
  • データ移行

ブログに必要なページと機能の検討

いざブログを再構築しようと思うと意外とページの種類が多いことに気付きます。

WordPress のよくある構成で、ざっと書き出しただけでも下記のような感じでしょうか。

  • 記事ページ
    • タグ付け
    • 目次
    • シンタックスハイライト
    • 記事共有リンク (Twitter など)
    • 関連記事
  • 一覧系ページ
    • トップページ
    • 新着順の記事一覧ページ
    • タグ一覧ページ
    • タグ別記事一覧ページ
    • カテゴリー一覧ページ
    • カテゴリー別記事一覧ページ
    • 著者ごとの記事一覧ページ
    • 年月ごとのアーカイブページ
  • ブログとしての機能
    • 記事検索・検索結果
    • 記事ごとのコメント

これでも十分多いのですが、サイトによってはもっと多様なこともあるでしょう。

すべてを移行するに越したことはありませんが、いきなりすべてそろえるのはなかなか大仕事です。

ということで初期段階では実装機能を絞ることで移行のハードルを下げることにしました。ただし後から追加したくなったときのことも考え、頭の片隅では実装方法を考えておきます。

記事ページが最優先

まず最も重要なのは、記事ページです。ブログですから記事がなければ、話にならないですね😂

記事ごとに必要な機能はまた後で検討しますが、記事自体が最優先なのはまちがいないでしょう。記事の質を改善するのは別途努力するとして、サイトとしてはなるべく読みやすく表示するように意識しなければなりません。

一覧ページは取捨選択

技術ブログの特徴として、ほとんどの読者は Google の検索結果から記事ページに直接流入してくる ということが挙げられます。さらに流入してきた読者の大部分は高い確率でほしい情報が得られたとしても検索ページに戻ります。つまり直帰率も本質的に高いということです。

アフィリエイト系ブログなら直帰率は死活問題でしょうが、当ブログの場合、読者が希望の情報を得ることが目的ですから、これ自体は大きな問題ではありません。

それを念頭におくと、下記のような 「ありがちな」一覧ページはそこまで重要でない ことが見えてきます。

  • トップページ
  • 新着順の記事一覧ページ
  • タグ一覧ページ
  • タグ別記事一覧ページ
  • カテゴリー一覧ページ
  • カテゴリー別記事一覧ページ
  • 著者ごとの記事一覧ページ
  • 年月ごとのアーカイブページ

企業のホームページや Yahoo! のような古典的なポータルサイトを除き、現代ではサイトに「トップページ」から流入することはほとんどありません。どちらかというと記事にたどり着いた読者が、他の記事やサイト自体に興味を持って、“意図的に”トップページや一覧ページに遷移する場合がほとんどだと考えられます。

もちろん読者が関連情報にリーチするためには重要なページなのですが、少なくとも IT 系のブログにおいては記事本体に比べると相対的に重要度は低くなります。

しかし興味をもっていただいた読者に提供できる関連情報がゼロ、というわけにもいきませんので、4 種類に絞りました。

  • トップページ
  • 新着順の記事一覧ページ
  • タグ一覧ページ
  • タグ別記事一覧ページ
  • カテゴリー一覧ページ
  • カテゴリー別記事一覧ページ
  • 著者ごとの記事一覧ページ
  • 年月ごとのアーカイブページ

「カテゴリー」と「タグ」は似た性質であり、どちらをどう記事に割り当てるか、というのは悩ましいポイントです。読者にとっても「カテゴリーの “Web”」と「タグの “Web”」があったとき、表示される内容が違えば混乱を招きます。よって「カテゴリー」という概念はなくし、 「タグ」に一本化しました。

また、「著者ごと」「年月ごと」もよほどその著者やサイト自体に関心をもたない限り、見られることがない一覧です。追加しようと思えば後でも生成できるため、ひとまずこれらは省略しました。「新着順の記事一覧」も省こうかと思いましたが、サイト全体の記事を見渡す方法がなくなってしまうのと、ページネーションの実装検証のため、これだけは初期に採用しました。

ブログとしての機能は後回し

CMS としての機能は前回で検討しましたが、ブログとして読者に提供する機能もあります。「よくある」機能としては「記事検索」や「コメント」でしょうか。

「記事検索」 は一覧ページと同様に、読者が希望のページを発掘するために使われますが、当ブログの場合は一覧ページと同様の理由で優先度はあまり高くないはずです。いずれは用意するつもりですが、サーバー側プログラム(バックエンド)を使わない場合、インデックスをどのように保持するかなど、検討が必要ですので、ひとまず除外しました。

「コメント」 は(一般的には)読者を「常連化」するための機能です。当ブログの場合は「役に立った」「助かりました」といったポジティブなフィードバックをいただくことが多く、著者のモチベーション維持にもなっています。

ただ、コメント機能は「エンドユーザーにコンテンツの入力させる」という性質上、 XSS や CSRF の対策も含め、かなりやっかいな機能でもあります。

また、 「静的ページ」に「動的」な要素を持ち込むことになるため、複雑性が増します。これまでにいただいたコメントを無駄にすることも避けたいため、何らかの形で入れたいとは思っていますが、まだ実現方法を検討している段階です。

運用ルールの検討

運用のしくみとサイト構成はある程度検討できました。次に記事を書いてもらったり、レビューをしてもらったりするには、ある程度の「運用ルール」が必要ですので、これを検討しました。

執筆ルール

まず記事を書かなくては始まりませんので、執筆するときのルールを考えました。

執筆者の ID

今回は執筆者全員が GitHub のアカウントをもっていることが前提のため、 執筆者の ID として GitHub のアカウント名を使うことにしました。

これにより、GitHub へのリンクを生成できたり、アバターも GitHub に設定したものが利用できたりするので、いろいろとシンプルにできます。Twitter や Gravatar のアカウントなんかでもいいかもしれません。

ディレクトリ構成

記事を格納するディレクトリ(フォルダ)構成は下記のように決めました。

GitHub アカウント名/
  年/
    記事slug/
      images/ 👈 画像ディレクトリ
        記事slug.{jpg,png} 👈 アイキャッチ画像
        その他の画像ファイル 👈 記事中の画像
      index.md 👈 記事本文

年ごとのディレクトリに分けたのは、記事数の多い著者の場合、ディレクトリが多すぎて、一覧性が悪くなるためです。

ただ、ディレクトリを分けてしまうと人間にわかりやすくなる反面、 Gatsby のデフォルトでは階層構造がそのままページの slug になってしまいます。たとえば kenzauros/2021/hogehoge/ の記事なら https://mseeeen.msen.jp/kenzauros/2021/hogehoge/ になってしまうのです。

従来の URL を継承するためにも、これを https://mseeeen.msen.jp/hogehoge/ として扱うよう Gatsby 側でカスタムしました。この部分については、後続の記事で紹介するつもりです。

記事フォーマット

ほぼ Gatsby のお作法のままですが、記事の Markdown ファイル (index.md) は、 冒頭部分に下記のような frontmatter を記述します。

---
title: <タイトル>
author: <GitHub アカウント名>
tags: [<タグ1>, <タグ2>, ...]
description: <説明>
---

ここから本文です。

## 大見出し

### 中見出し

思うがままにどんどん書きましょう。

ここで frontmatter に date がないことに気付かれたかもしれませんが、 「スケジュール投稿」を実現するため、執筆時点では date を記入せず、マージ時に自動的に挿入することにしました。

その他の執筆ルール

  • 下書き: まだレビューに回さない段階では手元のコミットで置いておく or プッシュしておく
  • ブランチ: ブランチ名は post/<slug> にする(後から slug を変更した場合でも変更は不要)
  • レビュー依頼: GitHub で release ブランチに向けて Pull Request を発行(基本的に 1 記事につき 1 PR)

データ移行

今回は新しいブログの立ち上げというわけではないため、必ず「データ移行」が伴います。

記事本文

記事本文については MySQL のテーブルにある記事データを Markdown に落とし込めばよさそうです。幸い当ブログでは WordPress 上でも Markdown で書いていたため、ここのハードルは低く済みました。

本文が HTML の場合でも特に移行記事を Markdown に統一したい場合を除き、そのまま Markdown の本文にしてしまえばいいのではないかと思います。

移行前の環境では phpMyAdmin が使えたため、 SQL を使ってデータを YAML ファイルに出力し、 Node.js のスクリプトで Markdown に一括変換しました。

記事内の画像

やっかいだったのは記事中で使われている画像でした。最終的にはスクリプトで画像リンクを抽出して fetch でダウンロード、名前を変換して格納する、という方法を取りました。さらにアップロードされている画像には巨大なサイズのものもあったため、一括でリサイズ・最適化も行いました。

この部分についてはまた別記事にてまとめたいと思いますが、ひとまず下記のようなディレクトリ構成の Markdown ファイルと画像ファイル群が得られたと仮定してください。

- 著者1
    - 年
        - 記事スラグ
            - images/ 👈 画像ディレクトリ
                - 記事スラグ.{jpg,png} 👈 アイキャッチ画像
                - 記事スラグ-*.拡張子 👈 記事中の画像
            - index.md 👈 記事本文
- 著者2
...

まとめ

Gatsby を使ったブログサイトについて、コンテンツや機能の検討内容とデータ移行について紹介しました。

次回はリポジトリや CI/CD などシステム構成について紹介します。

kenzauros