Analytics Tracking について
Next.jsアプリの分析とイベント計測を実装するスキルです。サービス設定、カスタムイベント、ファネル、A/Bテストを、プライバシーに配慮して進める方法を案内します。
主な機能
- 01Google Analytics 4とVercelの設定
- 02PostHog連携の案内
- 03カスタムイベント計測のパターン
- 04コンバージョンファネル計測
- 05A/Bテストと機能フラグ
- 06プライバシーと同意の実践
活用シーン
- 01Next.jsアプリへの分析機能追加
- 02複数段階の登録コンバージョン測定
- 03画面のA/Bテスト実施
- 04同意に配慮したイベント計測
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jmsktm/ claude-settings --skill analytics-trackingインストール後、Claude Code で/analytics-trackingを入力して読み込まれたか確認します。
詳細
アナリティクスとトラッキングのスキル
Next.js アプリケーション向けの、包括的なアナリティクスおよびイベントトラッキングの実装です。基本的なページビューから複雑なコンバージョンファネルまで、プロバイダーとの連携、カスタムイベントシステム、A/B テスト、プライバシーコンプライアンスなど、データに基づく意思決定に必要なすべてを網羅しています。
ユーザーの操作を追跡し、コンバージョンファネルを測定し、実験を実施して、ユーザー行動に関する実用的なインサイトを得ましょう。プライバシーコンプライアンスを維持しながら、Vercel Analytics、PostHog、Mixpanel、Google Analytics などの人気のアナリティクスプラットフォームと連携できます。
主なワークフロー
ワークフロー 1:Google Analytics 4(GA4)のセットアップ
目的: 包括的なウェブアナリティクスのために Google Analytics を実装します
手順:
- @next/third-parties パッケージをインストールします
- レイアウトに GoogleAnalytics コンポーネントを追加します
- カスタムイベントトラッキングを実装します
- コンバージョン目標を設定します
実装:
// Install
// npm install @next/third-parties
// app/layout.tsx
import { GoogleAnalytics } from '@next/third-parties/google'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<GoogleAnalytics gaId="G-XXXXXXXXXX" />
</body>
</html>
)
}
// Track Events
'use client'
export function TrackableButton() {
const handleClick = () => {
window.gtag('event', 'button_click', {
event_category: 'engagement',
event_label: 'cta_button',
value: 1
})
}
return <button onClick={handleClick}>Click Me</button>
}
ワークフロー 2:Vercel Analytics との連携
目的: Vercel へのデプロイで設定不要のアナリティクスを利用します
手順:
- @vercel/analytics をインストールします
- Analytics コンポーネントを追加します
- カスタムイベントを追跡します
実装:
// npm install @vercel/analytics
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react'
import { SpeedInsights } from '@vercel/speed-insights/next'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Analytics />
<SpeedInsights />
</body>
</html>
)
}
// Track Custom Events
import { track } from '@vercel/analytics'
track('Purchase', { amount: 99.99, currency: 'USD' })
ワークフロー 3:PostHog(オープンソースのアナリティクス)
目的: フィーチャーフラグとセッションリプレイを備えた、フル機能のプロダクトアナリティクスを利用します
手順:
- posthog-js をインストールします
- PostHog プロバイダーを作成します
- イベントトラッキングを実装します
- フィーチャーフラグを設定します
実装:
// lib/posthog.ts
import posthog from 'posthog-js'
export function initPostHog() {
if (typeof window !== 'undefined') {
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com',
loaded: (posthog) => {
if (process.env.NODE_ENV === 'development') posthog.debug()
}
})
}
}
// app/providers.tsx
'use client'
import { useEffect } from 'react'
import { initPostHog } from '@/lib/posthog'
export function Providers({ children }) {
useEffect(() => {
initPostHog()
}, [])
return <>{children}</>
}
// Track Events
import posthog from 'posthog-js'
posthog.capture('user_signed_up', {
plan: 'pro',
source: 'landing_page'
})
ワークフロー 4:カスタムアナリティクスシステム
目的: 統合されたアナリティクス抽象化レイヤーを構築します
実装:
// hooks/use-analytics.ts
'use client'
import { useCallback } from 'react'
type EventProperties = Record<string, any>
export function useAnalytics() {
const track = useCallback((eventName: string, properties?: EventProperties) => {
if (typeof window !== 'undefined') {
// Google Analytics
window.gtag?.('event', eventName, properties)
// PostHog
window.posthog?.capture(eventName, properties)
// Custom backend
fetch('/api/analytics/track', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event: eventName,
properties,
timestamp: new Date().toISOString(),
url: window.location.href,
referrer: document.referrer,
})
}).catch(() => {})
}
}, [])
const identify = useCallback((userId: string, traits?: EventProperties) => {
if (typeof window !== 'undefined') {
window.gtag?.('config', 'GA_MEASUREMENT_ID', { user_id: userId })
window.posthog?.identify(userId, traits)
}
}, [])
const page = useCallback((pageName: string, properties?: EventProperties) => {
if (typeof window !== 'undefined') {
window.gtag?.('event', 'page_view', {
page_title: pageName,
...properties
})
window.posthog?.capture('$pageview', properties)
}
}, [])
return { track, identify, page }
}
ワークフロー 5:コンバージョンファネルのトラッキング
目的: 複数ステップのコンバージョンファネルを追跡して分析します
実装:
// lib/funnel.ts
type FunnelStep =
| 'landing'
| 'signup'
| 'onboarding'
| 'first_action'
| 'activation'
export class FunnelTracker {
private steps: FunnelStep[] = []
trackStep(step: FunnelStep, properties?: Record<string, any>) {
this.steps.push(step)
track('Funnel Step Completed', {
step,
step_number: this.steps.length,
funnel_id: 'user_activation',
...properties
})
// Track drop-off if user hasn't progressed
setTimeout(() => {
if (this.steps[this.steps.length - 1] === step) {
track('Funnel Drop Off', {
at_step: step,
steps_completed: this.steps.length
})
}
}, 60000)
}
}
// Usage
const funnel = new FunnelTracker()
funnel.trackStep('landing')
funnel.trackStep('signup', { method: 'email' })
funnel.trackStep('onboarding', { completed_steps: 3 })
ワークフロー 6:A/B テストの実装
目的: 統計的有意性のある統制実験を実施します
実装:
// lib/ab-test.ts
'use client'
import { useState, useEffect } from 'react'
type Variant = 'A' | 'B'
export function useABTest(testName: string): Variant {
const [variant, setVariant] = useState<Variant>('A')
useEffect(() => {
const key = `ab_test_${testName}`
let userVariant = localStorage.getItem(key) as Variant
if (!userVariant) {
userVariant = Math.random() > 0.5 ? 'A' : 'B'
localStorage.setItem(key, userVariant)
track('AB Test Assigned', {
test_name: testName,
variant: userVariant
})
}
setVariant(userVariant)
}, [testName])
return variant
}
// Usage
function PricingPage() {
const variant = useABTest('pricing_layout')
if (variant === 'A') {
return <PricingLayoutA />
}
return <PricingLayoutB />
}
// Advanced A/B Testing with PostHog
import { useFeatureFlagEnabled } from 'posthog-js/react'
export function PricingPage() {
const showNewPricing = useFeatureFlagEnabled('new-pricing-layout')
if (showNewPricing) {
return <NewPricingLayout />
}
return <OldPricingLayout />
}
クイックリファレンス
| 操作 | コマンド/トリガー |
|---|---|
| 基本設定 | 「アプリにアナリティクスを追加」 |
| イベントの追跡 | 「[イベント名] を追跡」 |
| ページビュー | 「ページビューを追跡」 |
| コンバージョン | 「コンバージョントラッキングを設定」 |
| A/B テスト | 「A/B テストを実装」 |
| フィーチャーフラグ | 「フィーチャーフラグを追加」 |
| ユーザーの識別 | 「ユーザーを識別」 |
| ファネル分析 | 「コンバージョンファネルを追跡」 |
追跡する一般的なイベント
ユーザー認証:
track('User Signed Up', { method: 'email' })
track('User Logged In', { method: 'google' })
track('User Logged Out')
エンゲージメント:
track('Button Clicked', { button_id: 'cta', location: 'hero' })
track('Link Clicked', { url: '/pricing', text: 'See Pricing' })
track('Video Played', { video_id: 'intro', duration: 120 })
track('Form Submitted', { form_id: 'contact', success: true })
Eコマース:
track('Product Viewed', { product_id: '123', name: 'Pro Plan' })
track('Product Added to Cart', { product_id: '123', quantity: 1 })
track('Checkout Started', { cart_total: 99.99 })
track('Order Completed', {
order_id: 'ORD-123',
total: 99.99,
items: 3
})
プライバシーと同意
// components/cookie-consent.tsx
'use client'
import { useState, useEffect } from 'react'
export function CookieConsent() {
const [showBanner, setShowBanner] = useState(false)
useEffect(() => {
const consent = localStorage.getItem('cookie_consent')
if (!consent) {
setShowBanner(true)
} else if (consent === 'accepted') {
initAnalytics()
}
}, [])
const accept = () => {
localStorage.setItem('cookie_consent', 'accepted')
setShowBanner(false)
initAnalytics()
}
const decline = () => {
localStorage.setItem('cookie_consent', 'declined')
setShowBanner(false)
}
if (!showBanner) return null
return (
<div className="fixed bottom-0 left-0 right-0 bg-gray-900 text-white p-4">
<p>We use cookies to improve your experience.</p>
<button onClick={accept}>Accept</button>
<button onClick={decline}>Decline</button>
</div>
)
}
ベストプラクティス
- プライバシーを最優先: ユーザーの同意とプライバシー規制(GDPR、CCPA)を尊重します
- 一貫した命名: イベント名には snake_case を使用します
- 豊富なコンテキスト: すべてのイベントに関連するプロパティを含めます
- ユーザーの識別: 匿名セッションと認証済みセッションを関連付けます
- イベント分類: イベントの命名規則を文書化します
- サンプリング: 大量のイベントにはサンプリングを使用します
- テスト: 本番環境に移行する前に、開発環境でトラッキングをテストします
- データ品質: イベントを送信する前に検証します
- パフォーマンス: イベントをまとめて送信し、メインスレッドをブロックしないようにします
- ドキュメント: イベント辞書を維持します
依存関係
# Vercel Analytics
npm install @vercel/analytics @vercel/speed-insights
# Google Analytics
npm install @next/third-parties
# PostHog
npm install posthog-js
# Mixpanel
npm install mixpanel-browser
エラー処理
- ネットワーク障害: イベントをローカルにキューイングし、再試行します
- トラッカーのブロック: アプリを壊すことなく、問題なく機能を縮退させます
- 無効なイベント: 送信前にイベントの構造を検証します
- レート制限: クライアント側でレート制限を実装します
- ユーザー ID の欠落: 識別されるまでは匿名 ID を使用します
パフォーマンスのヒント
- 重要度の低いトラッキングには
requestIdleCallbackを使用します - 複数のイベントをまとめて単一のリクエストで送信します
- アナリティクススクリプトを遅延読み込みします
- ページのアンロード時のイベントには Beacon API を使用します
- キー入力のたびにトラッキングすることは避けます
- 頻度の高いイベントをサンプリングします
このスキルを使用する場面
次の場合にこのスキルを呼び出します:
- アナリティクストラッキングを設定するとき
- コンバージョントラッキングを実装するとき
- A/B テストを作成するとき
- ユーザー行動を追跡するとき
- ファネルを設定するとき
- GDPR コンプライアンスを実装するとき
- アナリティクスの問題をデバッグするとき
- コンバージョンを最適化するとき
- アナリティクスダッシュボードを作成するとき
- カスタムイベントを追跡するとき