メインコンテンツへスキップ
← 記事一覧に戻る
·収益化·12 min read

個人開発SaaSのプロダクト分析2026 — PostHog+SupabaseでFree→有料転換ファネルを可視化する

PostHogSupabase個人開発プロダクト分析SaaS
個人開発SaaSのプロダクト分析2026 — PostHog+SupabaseでFree→有料転換ファネルを可視化する

結論:「なぜ転換しないのか」はデータを見るまでわからない

個人開発SaaSで無料ユーザーが増えても有料転換が進まない——そんな状況に陥ったとき、多くのエンジニアは「機能が足りないのでは」「価格が高すぎるのでは」と感覚で対処しようとします。しかし感覚で打ち手を変えてもほぼ当たりません。

必要なのは計測です。ユーザーがどこで止まっているか、どの機能を使った人が有料転換しているか、そのデータがあれば打ち手は絞り込めます。

PostHogはセルフホストも選択できるオープンソースのプロダクト分析ツールです。無料クラウド版では月100万イベントまで無料で使えるため、個人開発SaaSの初期フェーズには十分すぎるほどのキャパシティがあります。SupabaseのUserテーブルと紐付けることで「プランごとのユーザー行動」まで掘り下げて分析できます。

Claude Crew Lab(Free → Standard ¥1,980 / Premium ¥4,980)のFree MVPを運用中です。PostHog Cloud(無料枠)をNext.js + Supabase構成に連携し、登録→ダッシュボード初訪問→コンテンツ閲覧→プラン確認ページの4ステップファネルをセットアップ済みです。現在はベースライン計測中のため数値は公開できませんが、節目ごとにBuild in Public記事で実測値を開示していきます。

この記事でわかること:

  • GA4だけではわからないプロダクト分析の視点
  • PostHog Cloud を Next.js App Router に組み込む手順
  • Supabase Auth ユーザーとPostHogをidentifyで紐付ける方法
  • Free→有料転換ファネルの設定方法
  • コホート分析でアクティブユーザーの特徴を把握する方法
  • フィーチャーフラグで機能を段階リリースする実装

GA4だけでは足りない理由

GA4はページビューとセッションの計測には優れていますが、プロダクトの個別ユーザー行動を追うには向いていません。

指標GA4PostHog
ページビュー・流入
ユーザー別行動の追跡△(匿名中心)◎(ログインユーザー)
転換ファネル△(限定的)◎(自由設計)
フィーチャーフラグ
コホート分析
セルフホスト可

SaaSで重要なのは「誰が」「どの機能を使ったあとに」「有料になったか」という個人単位のデータです。そのためにはuser_idを軸にしたイベントトラッキングが必要で、これはPostHogが得意とする領域です。


PostHog のセットアップ

1. プロジェクト作成

PostHog Cloudでアカウントを作成してプロジェクトを新規作成します。無料プランでは月100万イベントまで利用可能です。Project Settings から API Key を取得します。

環境変数に追加:

NEXT_PUBLIC_POSTHOG_KEY=phc_xxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

2. パッケージのインストール

npm install posthog-js posthog-node

3. クライアントサイドの初期化(Provider)

src/providers/posthog-provider.tsx:

'use client'

import posthog from 'posthog-js'
import { PostHogProvider as PHProvider } from 'posthog-js/react'
import { useEffect } from 'react'

export function PostHogProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
      api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
      person_profiles: 'identified_only',
      capture_pageview: false, // App Routerでは手動管理
    })
  }, [])

  return <PHProvider client={posthog}>{children}</PHProvider>
}

src/app/layout.tsxでラップ:

import { PostHogProvider } from '@/providers/posthog-provider'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ja">
      <body>
        <PostHogProvider>{children}</PostHogProvider>
      </body>
    </html>
  )
}

4. ページビューのトラッキング

App Routerではルート変更の検知が必要です。src/components/posthog-page-view.tsx:

'use client'

import { usePathname, useSearchParams } from 'next/navigation'
import { useEffect } from 'react'
import { usePostHog } from 'posthog-js/react'

export function PostHogPageView() {
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const posthog = usePostHog()

  useEffect(() => {
    if (pathname && posthog) {
      let url = window.origin + pathname
      if (searchParams.toString()) {
        url += `?${searchParams.toString()}`
      }
      posthog.capture('$pageview', { '$current_url': url })
    }
  }, [pathname, searchParams, posthog])

  return null
}

Supabase Auth との紐付け(identify)

ここが最も重要な実装です。PostHogはデフォルトで匿名IDを生成しますが、Supabaseのユーザーが認証済みになったタイミングでposthog.identify()を呼ぶことで、それ以降のイベントがユーザー単位で紐づきます。

src/components/auth-tracker.tsx:

'use client'

import { createClient } from '@/lib/supabase/client'
import { useEffect } from 'react'
import { usePostHog } from 'posthog-js/react'

export function AuthTracker() {
  const supabase = createClient()
  const posthog = usePostHog()

  useEffect(() => {
    const { data: { subscription } } = supabase.auth.onAuthStateChange(
      (event, session) => {
        if (event === 'SIGNED_IN' && session?.user) {
          const user = session.user
          posthog.identify(user.id, {
            email: user.email,
            plan: user.user_metadata?.plan ?? 'free',
            created_at: user.created_at,
          })
        }

        if (event === 'SIGNED_OUT') {
          posthog.reset()
        }
      }
    )

    return () => subscription.unsubscribe()
  }, [supabase, posthog])

  return null
}

これをLayout内に配置することで、ログイン状態が変わるたびにPostHogのユーザー属性が更新されます。

プランをユーザープロパティとして同期

サブスクリプションのプランが変わったタイミングでPostHogのプロパティも更新します:

import posthog from 'posthog-js'

export function syncPlanToPostHog(newPlan: 'free' | 'standard' | 'premium') {
  posthog.setPersonProperties({ plan: newPlan })
  posthog.capture('plan_changed', { to_plan: newPlan })
}

Free→有料転換ファネルの設定

PostHogのダッシュボードで Funnels を開き、以下のイベントシーケンスを設定します:

Step 1: $pageview (where: /dashboard)      ← ダッシュボード訪問
Step 2: $pageview (where: /articles/*)     ← コンテンツ閲覧
Step 3: $pageview (where: /pricing)        ← 価格ページ訪問
Step 4: checkout_started                   ← Checkout開始
Step 5: subscription_created              ← 有料転換

checkout_startedsubscription_createdはコード側でカスタムイベントを発火します:

// Stripe Checkout APIを呼ぶ前
posthog.capture('checkout_started', {
  plan: selectedPlan,
  price_id: priceId,
})

// Stripeのsuccess URLリダイレクト先
posthog.capture('subscription_created', {
  plan: selectedPlan,
})

ファネルの各ステップで「ドロップ率」が可視化されます。最もドロップが多いステップが、まず改善すべき箇所です。


コホート分析:アクティブユーザーの特徴を探す

「有料転換したユーザー」と「していないユーザー」のコホートを作り、行動の差を比較します。

PostHog の Cohorts で以下を作成します:

  • コホートA: subscription_created イベントを過去30日以内に発生させたユーザー
  • コホートB: 登録後30日経過してもまだfreeプランのユーザー

2つのコホートを比較して、コホートAが多く使っていた機能イベントを探します。その機能が「転換のキー行動」です。見つかったら、新規ユーザーをそのキー行動に誘導するオンボーディングを強化します。

このアプローチは「どの機能が転換に貢献するか」を感覚ではなくデータで見つけられる点で、機能開発の優先度判断にも使えます。


フィーチャーフラグで機能を段階リリース

PostHogのFeature Flagsを使えば、特定ユーザーセグメントだけに機能を先行公開できます。

サーバーサイドでのフラグ評価(Next.js App Router):

import { PostHog } from 'posthog-node'

const serverPostHog = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
  host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
})

export async function isFeatureEnabled(
  flag: string,
  userId: string
): Promise<boolean> {
  const enabled = await serverPostHog.isFeatureEnabled(flag, userId)
  return enabled ?? false
}

クライアントサイドでの利用:

'use client'

import { useFeatureFlagEnabled } from 'posthog-js/react'

export function NewDashboardWidget() {
  const enabled = useFeatureFlagEnabled('new-dashboard-widget')

  if (!enabled) return null

  return <div>新しいウィジェット</div>
}

これにより「Standardプラン以上のユーザーだけに新機能を先行公開→反応を見てから全体展開」というリリースフローが実現できます。A/Bテスト機能と組み合わせれば、料金ページのコピーや導線の比較検証も可能です。


で、どう稼ぐ?

プロダクト分析は「データを集める」ことが目的ではなく、収益につながる行動を見つけて強化するために使います。

実践的な活用パターン

パターン1: コア行動を見つけてオンボーディングを最適化

転換ファネルとコホート比較で「この操作をした人が転換しやすい」というキー行動を特定します。登録直後のステップメールや案内UIをそのキー行動に誘導する設計に変えることで、転換率の改善が期待できます。

パターン2: 離脱の集中箇所に絞って改修

ファネルで最もドロップ率が高いステップを一点集中で改善します。全体を均等にブラッシュアップするより、ボトルネック1点の解消が転換率全体に効きやすいとされています。

パターン3: A/Bテストで価格表示を最適化

フィーチャーフラグを使って料金ページの文言を2パターン用意し、checkout_startedイベントの発生率を比較します。感覚でコピーを変えるより、データで検証してから全体適用できます。

SaaS業界の参考値(ChartMogul/Baremetrics公開データより)

  • Free→有料転換率の一般的な範囲: 2〜8%
  • プロダクト分析でオンボーディングを最適化した場合の改善幅: +1〜3%(施策・業種によって幅がある)

上記は業界ベンチマークです。Claude Crew Labは計測中のため、実測値が出た時点でBuild in Public記事として公開します。

収益化への橋渡し

PostHog単体では売上は増えません。計測→仮説→改善のサイクルを回すことで初めて数字が動きます。まず計測基盤を整えること、そしてデータから改善アクションを1つ実行することが最初のステップです。


関連記事

個人開発のメール自動化2026

Resend+SupabaseでFree→有料転換を仕組み化する実践ガイド。ファネル改善と合わせて取り組む序盤の一手。

個人開発のサブスク・月額課金設計完全ガイド2026

Stripe+Supabaseで¥980〜¥4,980の3階層サブスクを実装する実践パターン。

個人開発の価格設計2026

月¥5万を目指す価格の設定方法と心理的価格設計の実践ガイド。

Claude Crew Lab Free — 毎月の実験記録をメールで

Claude Code × 個人開発のリアルな事故・発見・SaaS アイデアを毎月第1月曜にお届け。登録で「収益化チェックリスト 15 項目」を無料プレゼント。

Lab Free 登録(月1回・無料)

この記事が役に立ったらシェア