🐼

2025年の個人開発:爆速で「パンダ特化型SNS」を作った技術スタック全公開

に公開

PanDoのバナー

この記事では、私が個人開発でリリースしたパンダ情報特化型アグリゲーションサービス「PanDo (パンドゥ)」について、そのアーキテクチャから実装のこだわりまでを紹介します。

https://n-scroller.vercel.app

導入:なぜ今、パンダなのか?

開発動機は、パンダに関する情報(動物園の公式サイト、ニュース、SNS)がWeb上に散在しており、それらを一元的に追いかけるのが困難だった点にあります。

X(旧Twitter)のように、タイムラインを眺めているだけで最新情報が「受動的」に入ってくるサービスを目指しました。また、フロントエンドからバックエンドまでを一気通貫で構築する経験を積みたいという技術的な目的もありました。

本記事では、PanDoの全体アーキテクチャ、実装でこだわった技術的なポイント、そしてサービスの大きな特徴であるオリジナルのドット絵デザインについて解説します。

1. PanDoの全体アーキテクチャ

PanDoは、フロントエンドとデータ収集バッチが明確に分離された構成を採用しています。

  • フロントエンド (Vercel): Next.js (App Router), React, SWR
  • バックエンド (DB): Supabase (PostgreSQL, Storage, Auth)
  • データ収集バッチ (GitHub Actions): PythonスクリプトをGitHub Actionsで毎時実行

システム構成図
システム構成図

この構成により、すべて無料枠での運用を実現しています。

2. データ収集バッチ (Python + GitHub Actions)

タイムラインの「元ネタ」となる記事データは、Pythonスクリプトによって収集されています。

多様な情報源

Pythonを使い、以下の3つのソースからパンダ関連情報を収集しています。

  1. NewsAPI (article_collector.py): 「panda」などのキーワードでニュースを検索します。
  2. Google Custom Search API (search_panda_images.py): 画像検索結果から元記事のURLを抽出し、ビジュアルリッチなフィードを実現します。
  3. RSSフィード (rss_collector.py): feedparser を利用し、主要な動物園やニュースサイトを直接巡回します。

DBへの保存と自動化

収集したデータはSupabase DBに upsert されます。article_url を重複キーとして設定しているため、重複した記事は自動的に無視(ignore)されます。

このPythonスクリプトは、GitHub Actionsのcron機能によって毎時自動で実行されています。

3. 実装した機能の全体像

フロントエンド (Next.js) では、SNSとして必要な体験を一通り実装しました。

フロントエンドのタイムライン
フロントエンドのタイムライン

  • 基本機能: いいね、ブックマーク、返信(コメント)、共有
  • 認証 (NextAuth): Googleログイン
  • マイページ機能: いいねした投稿一覧、ブックマークした投稿一覧、プロフィール編集
  • UX向上機能: 無限スクロール、多言語対応(日/英)、インタラクティブ・チュートリアル
  • その他: インフォメーションページ(About, Policyなど)

これらの機能を実装する上で、特にこだわった技術ポイントを次に紹介します。

4. フロントエンドでこだわった実装ポイント

① 認証:NextAuth v4 + SupabaseAdapter

「いいね」や「ブックマーク」機能の基盤として、認証機能は不可欠でした。NextAuth.js (v4) を採用し、@auth/supabase-adapter を利用しています。これにより、Google認証で取得したユーザー情報がSupabaseの next_auth.users テーブルに自動で保存・連携されます。

加えて、プロフィール編集画面 (profile/page.tsx) も作成し、Supabase Storageへのアイコン画像アップロード (api/profile/upload-icon) や、users テーブルの name 更新 (api/profile) といった、一連のユーザー管理機能も実装しました。

② 爆速のUX:「楽観的UI」と「ページアニメーション」

SNSにおいて操作の「体感速度」は非常に重要です。PanDoでは2つの工夫を取り入れています。

  • 楽観的UI (Optimistic UI):
    「いいね」ボタンを押した際、APIからの応答を待たずに、まずUI(アイコンとカウント)を即時変更します。これは useSWRInfinite が提供する mutate 関数と、自前の onOptimisticUpdate コールバックを連携させて実現しています。これにより、ユーザーはネットワーク遅延を感じることなく、円滑な操作が可能です。

フロントのユーザー入力
フロントエンドのユーザー入力

  • ページ遷移アニメーション:
    framer-motion を導入し、layout.tsxAnimatePresencetemplate.tsx を用いて、ページ遷移にアニメーションを加えています。記事詳細ページ (/article/[id]) へは「下からスライドイン」、それ以外のページは「フェードイン」と、usePathname でパスに応じてアニメーションを分岐させているのがこだわりです。

③ 多言語対応 (i18n)

LanguageProvider (app/components/LanguageProvider.tsx) というReact Contextを作成し、useLanguage フック (const { t } = useLanguage()) を通じて、UIの文言を日本語と英語で動的に切り替えられるようにしました。

多言語対応(日本語)
多言語対応(日本語)

多言語対応(英語)
多言語対応(英語)

また、date-fns のロケールも動的に切り替えることで、「3時間前」 / 「3 hours ago」といった相対時間の表示も適切に連動させています。

④ 迷わせないオンボーディング:インタラクティブ・チュートリアル

多機能なサービスでユーザーが迷わないよう、初回ログイン時に主要機能(いいね、ブックマーク等)を学べるインタラクティブ・チュートリアルを実装しました。

チュートリアル
チュートリアル

localStorage で表示済みかを判定し、useLayoutEffectdocument.querySelector を用いて、対象のUI要素を動的にハイライトし、ポップオーバーで説明を表示する仕組みです。

⑤ 開発者フレンドリーなバグ報告フォーム

インフォメーションページ (/links) の中に「お問い合わせ」ページ (/links/contact) を設けています。

バグ報告フォーム
バグ報告フォーム

ここには、単なる連絡先メールアドレスに加え、バグ報告専用のGoogleフォームを埋め込んでいます。
技術的な工夫として、このページはクライアントコンポーネント ("use client") になっており、useEffect を使ってユーザーの navigator.userAgent を自動取得します。
そして、そのUserAgent情報をURLパラメータとして付与したGoogleフォームのURLを iframesrc に動的にセットしています。

これにより、バグ報告を受け取る際に、開発者 (私) がデバッグに必要な「どのブラウザ/OSで起きたか」という環境情報を、ユーザーに入力してもらう手間なく自動で受け取れるようになっています。

5. PanDoの「顔」:オリジナルのドット絵デザイン

ここが、私が最もこだわったポイントであり、このサービスの最大の特徴です。

統一された世界観

UIはXライクなUIを参考にしつつ、より洗練させるために白黒ベースで統一しました。その上で、アイコンやバナーに温かみのあるドット絵を採用し、独自のレトロモダンな世界観を目指しました。

フロントエンドの見た目
フロントエンド

クリエイターとのコラボレーション

このUIの核となっているドット絵の多くは、ドット絵クリエイターの haharmanさん (@_haharman) に制作依頼したものです。

@haharmanの紹介
@_haharmanの紹介

「押す楽しさ」をドット絵アニメで

単に静的な画像を配置するだけではありません。「いいね」や「ブックマーク」ボタンは、押した瞬間にオリジナルのアニメーションGIF (like_anime_up.gifなど) が再生されるように実装しました。

いいねのアニメーション
いいねのアニメーション

ブックマークのアニメーション
ブックマークのアニメーション

この「押す楽しさ」が、前述した「楽観的UI」の高速なレスポンスと組み合わさることで、PanDo独自の心地よい操作感を生み出せたと考えています。

個人開発であっても、クリエイターの方と協力することで、サービスのクオリティと独自性が格段に向上することを実感しました。

6. 今後の展望

PanDoはまだ始まったばかりです。今後は以下の機能を追加・改善していく予定です。

  • ダークモード対応
  • AI要約機能 (パンダの投稿)
  • 検索機能
  • ハッシュタグ機能
  • ユーザー投稿 (UGC) 機能
  • コメント機能強化
  • 通知機能

7. まとめ

「自分が欲しいもの」を起点に、Next.js + Python + Supabase というモダンな(そして無料枠で運用できる)構成でパンダSNS「PanDo」を開発しました。

楽観的UIやアニメーション、そして何よりもオリジナルのドット絵デザインといったUXにこだわりを詰め込んでいます。

パンダが好きな方も、この技術スタックに興味がある方も、ぜひ一度触ってみて、フィードバックをいただけると大変励みになります。

Discussion