The Cave Project
男性向けリトリートを運営する団体のための、マーケティングサイト、管理画面、参加申込パイプライン。
THE CAVE
Four Pillars. One Platform.
- 公開ページ
- 8+
- DBマイグレーション
- 17
- 完了フェーズ
- 6/6

- クライアント
- The Cave Project
- 業種
- 信仰に基づく団体
- 創設者
- El Hosseine, Ayoub & Oussama
- ステータス
- 完了
- 期間
- 2026年3月〜4月 · 8週間
- 対応範囲
- マーケティングサイト、管理画面、参加申込パイプライン
01 概要
クライアントは誰か
The Cave Projectは、四つの柱を軸にした、信仰に基づく男性向けの団体です。柱とは、霊的な強さ、心の強さ、身体の回復、感情の整理のこと。リトリートやイベント、集まりを運営しています。日々の雑音から離れ、すっきりした気持ちと目的意識を持って戻ってくるための、きちんと組み立てられた体験です。名前には意図があります。洞窟は孤立ではなく、リトリート(静かに身を引く場所)を表しています。
02 課題
どんな課題を抱えていたか
The Cave Projectには、まともなデジタル上の拠点がありませんでした。ブランドの土台は、内省、自然、そして物事を丁寧に行うこと。テンプレートのサイトでそれを担えるはずもありませんでした。もっと現実的な話をすれば、運営面にはそもそも仕組みがありませんでした。
ブランドにふさわしいウェブ上の存在感がない
テンプレートのサイトでは、リトリートで参加者に約束している内容の重みを支えきれませんでした。デジタル上の体験も、リトリートそのものの水準に見合う必要がありました。意図が行き届き、練り込まれていて、見る人に求める注目に見合うものです。
参加申込の仕組みがない
リトリートに関心を持った人は、メールやDMで連絡してきました。創設者には、誰が申し込んだのか、誰と話したのか、誰を受け入れたのかを追う手段がありませんでした。関心が増えるにつれて、このやり方はあっという間に回らなくなります。
コンテンツの更新に毎回開発者が必要
リトリートの告知、リソースの追加、参加者の声の差し替え。どれもコードの変更と再デプロイが必要でした。3人のチームにとっては、不便どころか本物のボトルネックです。
スパム対策がない
公開されているフォームには、必ずボットが寄ってきます。受信トレイはきれいに保ちたい。けれど、本当に申し込みたい人の前にCAPTCHAを置きたくはない。これはリトリートの参加申込であって、メルマガの登録ではないからです。
03 解決策
どう解決したか
プラットフォームは、公開サイト、管理画面、バックエンドの3層でつくりました。それぞれ独立して設計し、先方のサーバーで動く1つのPocketBaseインスタンスでつないでいます。
公開サイトはNext.jsのアプリケーションで、スクロール連動のストーリーテリングに重点を置いています。トップページではヒーローのシーケンスを固定し、放射状のワイプで四つの柱を表示します。続いて各柱を順に見せていきますが、そのうち一つはスクロール位置に連動したコマ送りのアニメーションで動きます。その先で、団体の沿革、参加者の声、創設者の紹介へと進みます。ページ間の移動にはブラウザー標準のビュー遷移API(View Transitions API)を使っており、一覧ページのカードが、そのまま詳細ページのヘッダーに変形するように遷移します。単に画面が切り替わるのではありません。
/adminの管理画面はCookie認証で、創設者がすべてを管理できます。ダッシュボードには新しい参加申込とメッセージが表示され、イベント、リソース、お知らせ、参加者の声を編集できます。参加申込は 新規 → 連絡済み → 受け入れ決定 のパイプラインを進みます。お問い合わせメッセージには、対応済みの印を付けられます。
- Site Next.js 15 公開サイト GSAPLenisView Transitions
- /admin Admin Panel Cookie認証 参加申込コンテンツ管理
- PB PocketBase Go + SQLite マイグレーション17件カスタムフック
- 霊的な強さ第一の柱
- 心の強さ第二の柱
- 身体の回復第三の柱
- 感情の整理第四の柱
- Next.js 15
- TypeScript
- GSAP ScrollTrigger
- Lenis
- View Transitions API
- PocketBase
- Go
- SQLite
- Docker
- Traefik
- Dokploy
04 プロジェクトの流れ
主なマイルストーンと期間
フェーズ1 2026年3月2日〜8日
基盤構築
リポジトリはGoワークスペースとNext.jsの構成にしました。開発用と本番用のDocker環境を用意し、PocketBaseを組み込み、環境変数からスーパーユーザーを初期登録して、新規デプロイの直後からすぐ管理を始められる状態にしました。
フェーズ2 2026年3月9日〜20日
コンテンツとイベント
スケジュール指定ができ、CTAも任意で付けられるお知らせバナー。スラッグ、ステータス、画像を持つイベントのコレクション。シードデータ。そして公開のプログラム案内ページ。
フェーズ3 2026年3月23日〜31日
リード獲得
イベントに紐づく参加申込、お問い合わせメッセージ、ハニーポットを組み込んだ2つの公開フォーム、そして内容を確認する管理画面。
フェーズ4 2026年4月1日〜8日
リソースライブラリ — 初期版
PDF、動画、SNSリンクを扱う初期スキーマ。アップロード、公開フラグ、並び順にも対応。
フェーズ5 2026年4月9日〜20日
リソースライブラリの再設計
Reactを1行も書く前に、単体のHTMLモックアップを6つ用意。スキーマは追加のみのマイグレーションで作り直し、新しい分類体系、トピックタグ、出典表記、再生時間、カバー画像、長文記事の本文を加えました。
フェーズ6 2026年4月21日〜30日
仕上げと公開
ライブラリのヒーロー行に出す注目リソース、PDFダウンロードのファイルサイズ表示、プログラム案内の絞り込みを支えるイベント種別の分類、そしてDokployの本番設定。
05 直面した壁と対処
どんな壁にぶつかり、どう乗り越えたか
スクロールで制御する動画
課題デザインでは、スクロールに合わせて前後に再生される動画クリップが求められていました。ところが、スクロールのたびに動画要素のシークを行うと、ブラウザーに負荷がかかりすぎます。トラックパッドでもマウスホイールでもひどくカクつき、意図した演出ではなく、壊れているように見えてしまいます。
解決策動画のシークは完全にやめました。クリップをあらかじめ99枚のWebPフレームに書き出し、スクロールのたびに画像を1枚差し替える方式にしています。結果は即座に反応し、どのデバイスでも完全に滑らかです。
目に見えないスパム対策
課題公開フォームには、ボットの送信が集まります。CAPTCHAを置けば、本当に申し込みたい人の体験を損ないます。これはリトリートの参加申込であって、メルマガの登録ではありません。その場面で手間をかけさせると、団体についての誤った印象を与えてしまいます。
解決策2つの公開フォームに、隠しフィールド「website」を置きました。人の目には見えませんが、ボットはすべての欄を埋めるため、バックエンドはこの欄に値が入っている送信を拒否します。チェックはサーバー側で動くので、APIを直接呼び出しても回避できません。
API経由のステータス改ざん
課題APIを呼び出せば誰でも参加申込のレコードを作成できるため、悪意のある第三者が、リクエストの内容を細工するだけで、最初から「受け入れ決定」にした申込を送れてしまいます。
解決策リクエストの内容にかかわらず、バックエンドが新しい参加申込のステータスを必ず「新規」に固定します。公開APIを通って、自分の申込を自分で昇格させる経路はありません。
管理画面のHTMLフォームのエッジケース
課題チェックされていないチェックボックスは何も送信されず、空のファイル入力は0バイトのファイルを送信し、空の数値欄は空文字列を送信し、選択をすべて解除した複数選択は項目を1つも送信しません。そのどれもが、編集者の意図とは違う形でデータベースに解釈されます。
解決策サーバーアクションの正規化レイヤーが、レコードを書き込む前に、それぞれのエッジケースをデータベースが期待する形に変換します。管理画面がデータを壊れた状態にすることはありません。
Docker内部URLと公開URLのルーティング
課題composeネットワークの内側では、Next.jsコンテナはサービス名でPocketBaseに到達できます。しかし、訪問者のブラウザーはそのアドレスを使えません。両者を混ぜると、サーバーレンダリングか、本番環境のすべての画像とファイルのリンクのどちらかが壊れます。
解決策初日から、2つのURLをコードベース全体で明確に分けました。Docker内のサーバーサイドレンダリングにはPB_URL_INTERNAL、ブラウザーが直接読み込むものにはNEXT_PUBLIC_PB_URLを使います。
06 Before / After
プロジェクト前後の状況の比較
| Before | After |
|---|---|
| ブランドに見合うサイトがない | サイト一式 — 公開ページ8ページ以上、スクロール連動のストーリーテリング、リトリートの世界観を伝えるアニメーション |
| 参加申込はメールとDMで受付 — 追跡もパイプラインもなく、取りこぼしやすい | イベントごとの参加申込フローと、管理画面で進める「新規 → 連絡済み → 受け入れ決定」の審査パイプライン |
| コンテンツを変えるたびに開発者が必要 — リトリート、リソース、参加者の声のどれも再デプロイが必要 | 創設者が自分たちで公開 — イベント、リソース、参加者の声、バナーまで、開発者を介さない |
| 公開フォームのスパム対策なし | 2つの公開フォームにハニーポットを設置 — ボットの送信は受信トレイに届かず、本当の申込者にCAPTCHAは不要 |
| リソースライブラリなし | 絞り込めるライブラリ — 詳細ページ、ファイルサイズ付きのPDFダウンロード、注目枠、長文記事の本文を備える |
| お知らせの掲載にデプロイが必要 | ワンクリックで有効にできる予約公開バナー(CTAリンクは任意) — 掲載のタイミングは創設者が決める |
| サーバーインフラなし | 先方のサーバーにDokploy経由でDockerデプロイ — Traefikによるルーティング、ヘルスチェック、永続ボリューム |
| サーバーを再構築するとスキーマとデータが失われる | スキーマとシードデータのすべてを、コードによる17件のマイグレーションから再構築 — プラットフォーム全体をゼロから再現できる |

07 クライアントにもたらした成果
クライアントはどんな価値を得たか
- 公開ページ
- 8+
- サイト · プログラム案内 · ライブラリ · お問い合わせ
- フェーズ
- 6 / 6
- 全フェーズ完了 · 納期どおり
- DBマイグレーション
- 17
- スキーマはコードで管理
- バックエンド
- バイナリ1つ
- PocketBase · マネージドDBなし
創設者だけで、すべてを管理できる。開発者は不要
リトリートの公開、ライブラリの選定、参加者の声の入れ替え、バナーの掲載。そのすべてが管理画面の中で完結します。コンテンツに関わる判断のたびに発生していた継続的なコストと待ち時間が、なくなりました。
参加申込は、バラバラのメッセージから管理されたキューに変わった
すべての申込者にステータスがあり、取りこぼしはありません。イベントごとの需要も一目でわかります。申込者には、送信したあと無反応のまま待たされるのではなく、きちんとした確認が届きます。
運用コストが低く、ロックインもない
バイナリ1つ、組み込みのデータベース、控えめなサーバー1台。CMSのライセンス料も、マネージドデータベースの請求もありません。しかも、すべてがコンテナ化されスキーマもコードにあるため、別の場所で2つのコンテナを動かせば、丸ごと引っ越せます。
サイト自体がブランドの役割を果たす
仕上がりの水準が、リトリートで参加者に約束している内容と釣り合っています。その水準は申込とお問い合わせの流れにもそのまま引き継がれ、第一印象が、団体の提供する体験と一貫しています。
08 得られた学び
このプロジェクトから何を学んだか
クライアントの規模に合ったバックエンドを選ぶ
PocketBaseとカスタムフックで、認証、ストレージ、ファイル処理、すぐに使える管理用APIが、1つのバイナリにまとまりました。一般的な構成に比べて可動部品はごくわずかで、3人の団体が自分たちで所有し、長く保守していくにも、はるかに現実的です。
セキュリティに関わることは、すべてサーバー側に置く
ハニーポット、固定されるステータス、シングルトンのルール、入力のサニタイズ。どれもバックエンドの仕事です。フロントエンドは使い心地を整え、バックエンドは正しさを守ります。この役割分担は、最後まで崩れませんでした。
解決策は、最適化ではなく手法の切り替えにあることもある
動画のシークのチューニングに、何日も費やすこともできました。画像シーケンスに切り替えたら、午後のうちに解決しました。手法そのものがブラウザーと戦っているなら、正しい対応は、戦わずに済む手法を探すことです。
コードで管理するマイグレーションが、プロジェクトの途中で真価を発揮した
フェーズ5でリソースのスキーマを大きく変える必要が出たとき、本来なら危険な手作業のデータベース操作になるところが、レビューでき、追加のみで元に戻せる一連の手順になり、どの環境にも自動で反映されました。
高くつくコードの前に、安いモックアップを
使い捨てのHTMLファイルを6つ用意したおかげで、リソースの再設計は、クライアントがすでに見て承認した方向に沿って、一度で済みました。モックアップにかかったのは午後いっぱい。省いていれば、Reactの書き直しで何日も失っていたはずです。
実際のサイトで動作中 · GSAP + View Transitions API + Lenis
主なインタラクション
各カードで、このプロジェクトのために作った主要なインタラクションの動くデモを見られます。
- スクロールシーケンス 99枚のWebP連番画像 · スクロールのたびに画像を1枚差し替え
- 放射状ワイプで柱を表示 conic-gradientワイプ · 四つの柱が順に登場
- 固定スクロールシーン 300vhのstickyトラック · 章ごとに進むトップページのストーリーテリング
- ビュー遷移モーフ 一覧のカードがページヘッダーに変形 · ブラウザー標準のAPI
- 参加申込パイプライン 新規 → 連絡済み → 受け入れ決定 · 管理画面での審査フロー
- スムーススクロール Lenisがサイト全体に適用 · どのデバイスでも自然な慣性スクロール


