前回、受注管理システムで「進捗ステータス列をあえて作らなかった」話を書いた。今回は、もう一つ作ったもの、このコーポレートサイトを作る過程でぶつかった話。
受注管理システムが一段落したあと、次に手をつけたのが自社のコーポレートサイトだった。考え方は同じだった。Webサイトも、プラグインで継ぎ足し拡張を重ねれば、いずれバージョン管理が大変になる。だったらサイトも、Gitでバージョン管理できる技術選定をするべきではないか。
そこで選んだのが、Payload CMSだった。コレクション定義やスキーマの設定がコードとして残り、Gitで構造ごと管理できる。しかも公式のWebsite Templateがあり、認証・SEO・レイアウトビルダーまで一通り揃っている。「これを応用すれば、速く作れるはずだ」と思って着手した。
テンプレートは、そのままでは動かなかった
しかし、実際に手を動かしてみると、期待通りにはいかなかった。Payload公式のテンプレートはMongoDBを前提に設計されていて、今回使うSupabase(PostgreSQL)とのあいだで、様々なところに不整合が出た。
このとき、選択肢は二つあった。MongoDB前提の設計を力技でPostgreSQL用に書き換えて動かし続けるか、無理に同じ設計にこだわらず別のやり方に切り替えるか。選んだのは後者だった。ブログ機能は、CMSの管理画面で持たせるのをやめて、記事をマークダウンファイルとしてGit管理下に直接コミットする形に変えた。実績紹介ページも、詳細ページ方式をやめて、一覧からGitHubへ直接飛ばす構成にした。判断の軸は変わらない。「Gitでバージョン管理ができるか」、それだけだった。
開発環境では、動いていた
テンプレートの相性問題を乗り越えて、開発環境でようやくすべてが動くところまで来た。管理画面から画像をアップロードし、各ページにカバー画像やヒーロー画像を設定する。ローカルで確認する限り、何の問題もなかった。
そのままVercelにデプロイした。
本番で、画像が全部消えた
公開されたサイトを開くと、画像が表示されていなかった。カバー画像、ヒーロー画像、本文中の画像、OGP用の画像――管理画面からアップロードしたものが、軒並み消えていた。
一方、ロゴやfaviconは無事だった。これらは管理画面を経由せず、最初からGitに直接コミットしていた画像だった。この違いから、原因を辿ることができた。
調べてみると、原因はシンプルだった。管理画面からアップロードした画像の保存先が、Gitの管理対象から除外される設定になっていたのだ。開発環境では、アップロードした画像がローカルのディスクにそのまま残るので、何の問題もなく表示される。しかし本番環境では、Gitにコミットされていないファイルはデプロイに含まれない。開発環境で「動いている」ように見えたのは、たまたまローカルにファイルが残っていただけで、実際にはその画像が一度もGitの管理下に入っていなかった。
動くことと、公開できることは、別問題だった
対処として、画像の保存先をローカルディスクから外部のクラウドストレージに切り替えた。導入自体は難しくなかったが、それだけでは終わらなかった。すでにアップロード済みだった画像は、切り替え後も置いてけぼりになる。一時的な移行スクリプトを書いて、既存の画像をすべて新しい保存先に移し替えた。
今回のことではっきりわかったことがある。ローカルで動作確認が取れていても、それは「公開できる」ことを何も保証しない。
それでも、Payload CMSを選び続ける理由
正直、今回のような壁は、他のCMSであればそもそも踏まなかったかもしれない。ノーコードのCMSなら、保存先の設定などユーザーが意識する必要もなく、最初から解決済みだったはずだ。
それでも、Payload CMSを使い続けようと思っている。多くのCMSは、後から機能を拡張しようとするとプラグインを追加する形になる。プラグインは便利な反面、品質のばらつきや競合、アップデートで壊れるリスクを抱え続けることになる。Payload CMSは違う。コレクションの定義もスキーマも、すべてコードとして残る。今回のようなつまずきも、原因をコードの中に、Git履歴として遡って特定できた。プラグインの奥で何が起きているか分からない状態だったら、もっと時間がかかっていたはずだ。
「動くこと」と「公開できること」のあいだにある壁を越えてでも、Gitで管理し続けられることには価値があると思っている。
設計の詳細は、GitHubで公開している。
https://github.com/kuros-works/kuros-corporate-site
実際のサイトも見てもらえる。
https://www.kuros-works.com/