個人開発SaaSのオンボーディング設計2026 — 登録→価値実感→有料転換を7日間で完結させる

無料ユーザーが増えるのに有料転換しない本当の理由
「登録者は増えているのに、誰も有料にならない」——個人開発SaaSを運営すると必ず一度は当たる壁です。
多くのエンジニアは機能不足や価格設定が原因と考えます。しかし実際にはオンボーディングの欠如が原因であることが多いです。登録直後の「どこから始めればいいかわからない」という体験がユーザーを離脱させています。
SaaSの世界では「Aha! moment(価値実感の瞬間)」という概念があります。ユーザーがプロダクトに対して「これは自分に必要だ」と感じる瞬間です。この瞬間への最短経路を設計することがオンボーディングの本質です。
Claude Crew Lab(Free → Standard ¥1,980 / Premium ¥4,980)のFree MVPを運用中です。登録直後のウェルカムメールはResend+Supabase Database Webhookで実装済み。7日間メールシーケンスはResend+pg_cronで構築中です。オンボーディングチェックリストUIの設計は完了し、実装に着手しています。Standard/Premiumはローンチ準備段階のため転換率は現在計測中です。
この記事でわかること:
- Aha! momentの定義と設計方法
- 7日間メールシーケンスの構成と実装(Resend + Supabase pg_cron)
- オンボーディングチェックリストUIの実装(Next.js App Router)
- PostHogでオンボーディング完了率を計測する方法
- 「で、どう稼ぐ?」— オンボーディング設計が収益に直結する理由
オンボーディング設計の3ステップ
ステップ1: Aha! momentを定義する
まずプロダクトの核心価値を1つ特定します。「登録してから最初にこれを体験したら価値がわかる」という瞬間です。
| プロダクト | Aha! moment の例 |
|---|---|
| タスク管理ツール | 最初のタスクを完了してチェックを入れた瞬間 |
| コード生成ツール | 最初のコードを生成してコピーした瞬間 |
| 分析ダッシュボード | 最初のグラフが表示された瞬間 |
| 学習コンテンツ | 最初の記事を読み終えた瞬間 |
Aha! momentへの最短経路を設計することが、オンボーディング全体の設計ゴールです。
ステップ2: 7日間メールシーケンスを設計する
Aha! momentまでに必要なステップをメールでナビゲートします。
| Day | 目的 | 内容 |
|---|---|---|
| Day 0 | ウェルカム | 登録お礼 + 最初にやること3つ |
| Day 3 | 活性化 | よくあるつまずきポイントと解決策 |
| Day 6 | 転換 | 有料プランで何が変わるか |
| Day 14 | 再活性化 | 未ログインユーザーへの関係性維持 |
Day 6のタイミングで有料転換CTAを出す理由は、ユーザーがプロダクトをある程度使った後に価値提案するためです。登録直後の売り込みは逆効果になります。
ステップ3: チェックリストUIで進捗を可視化する
ダッシュボードにオンボーディングチェックリストを常設し、「次にやること」を常に明確にします。ユーザーが「何をすればいいか」で迷う時間をゼロにすることが目標です。
実装:7日間メールシーケンス
前回のメール自動化記事で紹介したResend + Supabase構成を拡張します。Day 14の再活性化メールを追加します。
email_sequencesテーブルへのDay 14追加
INSERT INTO email_sequences (user_id, user_email, user_name, day, send_at)
VALUES (
$1, $2, $3, 14,
NOW() + INTERVAL '14 days'
)
ON CONFLICT (user_id, day) DO NOTHING;
ON CONFLICT DO NOTHING で重複送信を防ぎます。
Day 14 再活性化メールテンプレート
src/lib/resend.ts の templates オブジェクトに追加します:
14: (name) => ({
subject: `${name}さん、最近いかがですか?`,
html: `<p>登録から2週間が経ちました。</p>
<p>まだ試せていない機能がありましたら、お気軽にご連絡ください。</p>
<p><a href="https://masatoman.net/dashboard">ダッシュボードを開く →</a></p>`,
}),
EmailSequenceDay 型も 0 | 3 | 6 | 14 に更新します。
実装:オンボーディングチェックリストUI
Supabaseにオンボーディング状態を保存
CREATE TABLE onboarding_steps (
user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE,
step text NOT NULL,
completed boolean DEFAULT false,
updated_at timestamptz DEFAULT NOW(),
PRIMARY KEY (user_id, step)
);
チェックリストコンポーネント
src/components/onboarding-checklist.tsx:
'use client'
import { createClient } from '@/lib/supabase/client'
import { usePostHog } from 'posthog-js/react'
import { useEffect, useState } from 'react'
const STEPS = [
{ key: 'profile_set', label: 'プロフィールを設定する' },
{ key: 'first_content', label: '最初のコンテンツを読む' },
{ key: 'dashboard_visit', label: 'ダッシュボードを確認する' },
]
export function OnboardingChecklist({ userId }: { userId: string }) {
const supabase = createClient()
const posthog = usePostHog()
const [completed, setCompleted] = useState<Record<string, boolean>>({})
useEffect(() => {
supabase
.from('onboarding_steps')
.select('step, completed')
.eq('user_id', userId)
.then(({ data }) => {
if (!data) return
const map: Record<string, boolean> = {}
data.forEach((row) => { map[row.step] = row.completed })
setCompleted(map)
})
}, [userId, supabase])
const toggle = async (step: string) => {
const next = !completed[step]
await supabase.from('onboarding_steps').upsert({
user_id: userId,
step,
completed: next,
updated_at: new Date().toISOString(),
})
setCompleted((prev) => ({ ...prev, [step]: next }))
if (next) {
const doneCount = Object.values({ ...completed, [step]: true }).filter(Boolean).length
posthog.capture('onboarding_step_completed', {
step,
total_completed: doneCount,
total_steps: STEPS.length,
})
}
}
const doneCount = Object.values(completed).filter(Boolean).length
const pct = Math.round((doneCount / STEPS.length) * 100)
return (
<div className="rounded-lg border p-4 space-y-3">
<div className="flex items-center justify-between">
<p className="font-medium text-sm">スタートガイド</p>
<span className="text-xs text-muted-foreground">{pct}% 完了</span>
</div>
<div className="w-full bg-muted rounded-full h-1.5">
<div
className="bg-primary h-1.5 rounded-full transition-all"
style={{ width: `${pct}%` }}
/>
</div>
<ul className="space-y-2">
{STEPS.map(({ key, label }) => (
<li key={key} className="flex items-center gap-2 text-sm">
<button
onClick={() => toggle(key)}
className={`w-4 h-4 rounded border flex-shrink-0 transition-colors ${
completed[key]
? 'bg-primary border-primary'
: 'border-muted-foreground'
}`}
aria-label={label}
/>
<span className={completed[key] ? 'line-through text-muted-foreground' : ''}>
{label}
</span>
</li>
))}
</ul>
</div>
)
}
ダッシュボードページで <OnboardingChecklist userId={user.id} /> として使います。
PostHogでオンボーディング完了率を計測する
前のコードで posthog.capture('onboarding_step_completed', ...) を送信しています。PostHogダッシュボードの Funnels に以下を設定します:
onboarding_step_completed (profile_set)
→ onboarding_step_completed (first_content)
→ onboarding_step_completed (dashboard_visit)
→ subscription_created
このファネルで「オンボーディング完了者」と「未完了者」の転換率差を可視化できます。設定の詳細はPostHog分析記事を参照してください。
業界ベンチマーク(Intercom・ChartMogul・Baremetricsの公開データ)では、オンボーディング完了ユーザーは未完了者に比べて有料転換率が2〜4倍高い傾向があるとされています。
で、どう稼ぐ?
オンボーディング設計が収益に直結する理由は単純です。有料転換を決めるのは機能の数ではなく体験の深さだからです。
ユーザーがプロダクトの核心価値を体験しないまま離脱するのは、「価値がない」のではなく「価値に辿り着けなかった」ためです。
個人開発SaaSで月¥5万を目指す場合の試算例(業界ベンチマーク試算、実測値ではありません):
| 施策 | 想定A(オンボーディングなし) | 想定B(オンボーディングあり) |
|---|---|---|
| 月間新規登録 | 100人 | 100人 |
| オンボーディング完了率 | 20% | 50% |
| 完了者の転換率(業界目安3〜8%) | 3% | 5% |
| 月間新規有料転換 | 6人 | 25人 |
| MRR(¥1,980/月想定) | ¥11,880 | ¥49,500 |
上記はあくまで試算例です。実際の数値はプロダクト品質・集客数・価格設定によって大きく変わります。
実装の優先順位は以下の通りです:
- Day 0ウェルカムメール(登録直後)— 最も重要。開封率が最高のタイミング
- チェックリストUI(ダッシュボードに常設)— 次のアクションを常に明確化
- Day 3活性化メール— つまずきポイントを先回りして解消
- Day 6転換CTA— 価値を感じた後のタイミングで有料提案
- PostHogファネル計測— どこで止まるかを可視化して改善
まずDay 0メールだけ実装して反応を確認するのが、個人開発らしい進め方です。動いてから改善する。
関連記事
個人開発のメール自動化2026 — Resend+Supabaseで登録→有料転換を仕組み化する実践ガイド
7日間メールシーケンスの基本実装。本記事のStep 2の前提となるResend+Supabase Webhook構成を解説しています。
個人開発SaaSのプロダクト分析2026 — PostHog+SupabaseでFree→有料転換ファネルを可視化する
PostHogの転換ファネル設計とコホート分析。オンボーディング計測の詳細な設定方法を解説しています。
個人開発SaaSのサブスク設計パターン2026
Free/Standard/Premiumのプラン設計と転換導線の全体像。オンボーディングの目的地となる有料プランの設計指針。
Claude Crew Lab Free — 毎月の実験記録をメールで
Claude Code × 個人開発のリアルな事故・発見・SaaS アイデアを毎月第1月曜にお届け。登録で「収益化チェックリスト 15 項目」を無料プレゼント。
Lab Free 登録(月1回・無料)
この記事が役に立ったらシェア