On this page

For AI agents: a documentation index is available at /docs/llms.txt. Append .md to any page URL for markdown, or send Accept: text/markdown.

Next.jsインストールガイド

このガイドでは、Next.jsアプリケーションでのAmplitudeのブラウザSDKのインストールと設定について説明します。 クライアント側とサーバー側の両方の設定も含まれます。

前提条件

  • Next.js 13.0以降。
  • Node.js 16.8以降。
  • APIキーを持つAmplitudeアカウント。

インストール

Unified SDKを推奨

Unified SDKは、アナリティクス、実験、セッションリプレイへのアクセスを単一のパッケージで提供します。Amplitudeは、新しいNext.jsプロジェクトにはこのアプローチを推奨しています。

パッケージマネージャーを使用してAmplitude SDKをインストールします。

# Recommended: Install Unified SDK (includes Analytics, Experiment, Session Replay)
npm install @amplitude/unified
# Or install Analytics SDK only
npm install @amplitude/analytics-browser

クライアント側のセットアップ

Amplitudeの初期化

Amplitudeモジュールを作成して、クライアント側でSDKを初期化します。

// amplitude.ts
"use client";
import * as amplitude from "@amplitude/unified";
async function initAmplitude() {
  await amplitude.initAll(process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY!, {
    analytics: {
      autocapture: true,
    },
  });
}
if (typeof window !== "undefined") {
  initAmplitude();
}
export const Amplitude = () => null;
export default amplitude;

アプリルーター(Next.js 13以降)

コンポーネントをインポートしてルートレイアウトに追加します。

typescript
// app/layout.tsx
import { Amplitude } from "@/amplitude";
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <Amplitude />
      <body>
        {children}
      </body>
    </html>
  );
}

ページルーター(レガシー)

ページルーターの場合は、_app.tsxでAmplitudeを初期化します。

typescript
// pages/_app.tsx
import '@/amplitude';
import type { AppProps } from 'next/app';
function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />;
}
export default MyApp;

コンポーネントでAmplitudeを使用する

typescript
// components/TrackingButton.tsx
"use client";
import amplitude from "@/amplitude";
export function TrackingButton() {
  const handleClick = () => {
    amplitude.track("Button Clicked", {
      buttonName: "CTA Button",
      page: window.location.pathname,
      timestamp: new Date().toISOString(),
    });
  };
  return <button onClick={handleClick}>Click Me</button>;
}

サーバー側のセットアップ

サーバーコンポーネントと API ルート

サーバー側のトラッキングには、ブラウザ SDK ではなく Node.js SDK を使用してください。

bash
npm install @amplitude/analytics-node

サーバー側のAmplitudeクライアントを作成します。

typescript
// lib/amplitude-server.ts
import {
  init,
  track,
  identify,
  flush,
  Identify,
} from "@amplitude/analytics-node";
// Initialize once
const amplitudeServer = init(process.env.AMPLITUDE_API_KEY!);
export async function trackServerEvent(
  eventName: string,
  userId?: string,
  eventProperties?: Record<string, any>,
) {
  try {
    track(eventName, eventProperties, {
      user_id: userId,
    });
    // Ensure events are sent before function ends
    await flush().promise;
  } catch (error) {
    console.error("Failed to track server event:", error);
  }
}
export async function identifyServerUser(
  userId: string,
  userProperties?: Record<string, any>,
) {
  try {
    const identifyObj = new Identify();
    // Set user properties if provided
    if (userProperties) {
      Object.entries(userProperties).forEach(([key, value]) => {
        identifyObj.set(key, value);
      });
    }
    identify(identifyObj, {
      user_id: userId,
    });
    await flush().promise;
  } catch (error) {
    console.error("Failed to identify user:", error);
  }
}

サーバー側クライアントをAPIルートに追加します。

typescript
// app/api/track/route.ts (App Router)
import { NextRequest, NextResponse } from "next/server";
import { trackServerEvent } from "@/lib/amplitude-server";
export async function POST(request: NextRequest) {
  const body = await request.json();
  const { eventName, userId, properties } = body;
  await trackServerEvent(eventName, userId, properties);
  return NextResponse.json({ success: true });
}
typescript
// pages/api/track.ts (Pages Router)
import type { NextApiRequest, NextApiResponse } from "next";
import { trackServerEvent } from "@/lib/amplitude-server";
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  if (req.method !== "POST") {
    return res.status(405).json({ error: "Method not allowed" });
  }
  const { eventName, userId, properties } = req.body;
  await trackServerEvent(eventName, userId, properties);
  res.status(200).json({ success: true });
}

ベストプラクティス

環境変数

APIキーを環境変数に保存します:

bash
# .env.local
NEXT_PUBLIC_AMPLITUDE_API_KEY=your_client_api_key
AMPLITUDE_API_KEY=your_server_api_key

セキュリティ上の注意事項

クライアント側のAPIキーにはNEXT_PUBLIC_プレフィックスのみを使用してください。サーバー側のAPIキーは決してクライアントに公開されるべきではありません。

ユーザーの識別情報。

認証後にユーザーを識別します。

// After successful login
const handleLogin = async (email: string, userId: string) => {
  // Client-side identification
  if (typeof window !== "undefined") {
    amplitude.setUserId(userId);
    amplitude.identify(
      new amplitude.Identify()
        .set("email", email)
        .set("loginTime", new Date().toISOString()),
    );
  }
  // Server-side identification (if needed)
  await fetch("/api/identify", {
    method: "POST",
    body: JSON.stringify({ userId, email }),
  });
};

自動ページビュー追跡

Amplitudeの自動キャプチャ機能は、Next.jsアプリケーションのページビューを自動的に追跡します。

// Page views are automatically tracked when you enable autocapture
amplitude.initAll(apiKey, {
  analytics: {
    autocapture: {
      pageViews: true, // Automatically tracks route changes
    },
  },
});

ページビューの設定

自動キャプチャ機能は、Next.jsのルート変更をインテリジェントに検出し、ページビューとしてそれらを追跡します。詳細な設定については、ページビューのトラッキングを参照してください。

セッションリプレイ連携

ユーザーセッションをキャプチャして、動作の把握や問題のデバッグを行います:

// Enable Session Replay with the Unified SDK
import * as amplitude from "@amplitude/unified";
amplitude.initAll(apiKey, {
  analytics: {
    autocapture: {
      sessions: true,
      pageViews: true,
      formInteractions: true,
    },
  },
  sessionReplay: {
    sampleRate: 0.5, // Sample 50% of sessions
  },
});

セッションリプレイ

セッションリプレイは、ユーザーセッションを視覚的に再生します。 詳細については、セッションリプレイのドキュメントを参照してください。

自動キャプチャとカスタムイベントの使用

Amplitudeの自動キャプチャ機能を使用して、一般的なやり取りを自動的に追跡できます。

// Enable comprehensive autocapture
amplitude.initAll(apiKey, {
  analytics: {
    autocapture: {
      sessions: true,
      pageViews: true,
      formInteractions: true,
      fileDownloads: true,
      elementInteractions: true, // Tracks clicks on buttons, links, and more.
    },
  },
});

自動キャプチャではカバーできないビジネス固有のイベントの場合:

typescript
// Usage for custom business events
"use client";
import amplitude from "@/amplitude";
export function ProductCard({ product }: { product: Product }) {
  const handleAddToCart = () => {
    amplitude.track('Product Added to Cart', {
      productId: product.id,
      productName: product.name,
      price: product.price,
      category: product.category,
    });
    // Add to cart logic
  };
  return (
    <div>
      <button onClick={handleAddToCart}>Add to Cart</button>
    </div>
  );
}

自動キャプチャとカスタムイベントの比較

自動キャプチャは、クリック、フォーム送信、ページビューなどの標準的な操作に対応します。「プロダクトがカートに追加されました」や「サブスクリプションがアップグレードされました」などのビジネスに固有のアクションには、カスタムイベントを使用してください。

Next.jsのビジュアルラベル付け

Amplitudeのビジュアルラベル付けを使用すると、コードを変更することなくブラウザで直接要素にタグ付けできます:

// Visual Labeling works automatically with autocapture enabled
amplitude.initAll(apiKey, {
  analytics: {
    autocapture: {
      elementInteractions: true, // Required for Visual Labeling
    },
  },
});

ビジュアルラベル付け

Amplitude Chrome拡張機能を使用してNext.jsアプリにアクセスすると、ページ内で発生したイベントを表示できます。

ミドルウェア連携

Next.jsミドルウェアを使用して、サーバー側のイベントを追跡します。

typescript
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
  // Track API requests
  if (request.nextUrl.pathname.startsWith("/api")) {
    // Log to server-side analytics
    console.log("API Request:", {
      path: request.nextUrl.pathname,
      method: request.method,
      timestamp: new Date().toISOString(),
    });
  }
  return NextResponse.next();
}
export const config = {
  matcher: ["/api/:path*"],
};

セッション管理

ログイン時にユーザーIDを設定し、ログアウト時にリセットします。

// utils/amplitude-session.ts
import * as amplitude from "@amplitude/unified";
export function handleUserSession() {
  // On login
  const onLogin = (userId: string, userProperties?: Record<string, any>) => {
    amplitude.setUserId(userId);
    if (userProperties) {
      const identify = new amplitude.Identify();
      Object.entries(userProperties).forEach(([key, value]) => {
        identify.set(key, value);
      });
      amplitude.identify(identify);
    }
  };
  // On logout
  const onLogout = () => {
    amplitude.setUserId(undefined);
    amplitude.reset();
  };
  return { onLogin, onLogout };
}

TypeScript のサポート

タイプセーフなイベントトラッキングを作成するには、Ampliを使用してください。

テスト

テストでAmplitudeをモックします。

// __mocks__/amplitude.ts
export const mockAmplitude = {
  initAll: jest.fn(),
  track: jest.fn(),
  identify: jest.fn(),
  setUserId: jest.fn(),
  reset: jest.fn(),
};
jest.mock('@amplitude/unified', () => mockAmplitude);
// In your tests
import { render, fireEvent } from '@testing-library/react';
import { TrackingButton } from '@/components/TrackingButton';
import { mockAmplitude } from '@/__mocks__/amplitude';
describe('TrackingButton', () => {
  it('tracks click event', () => {
    const { getByText } = render(<TrackingButton />);
    fireEvent.click(getByText('Click Me'));
    expect(mockAmplitude.track).toHaveBeenCalledWith(
      'Button Clicked',
      expect.objectContaining({
        buttonName: 'CTA Button',
      })
    );
  });
});

デバッグ

開発中にデバッグモードを有効にします。

// Development configuration
amplitude.initAll(apiKey, {
  analytics: {
    logLevel: amplitude.Types.LogLevel.Debug,
    minIdLength: 1, // Allow shorter IDs in development
    serverUrl: process.env.NEXT_PUBLIC_AMPLITUDE_SERVER_URL, // Custom server URL if needed
    autocapture: true,
  },
});

ブラウザコンソールでAmplitudeログを確認してください。

  • イベントトラッキングの確認。
  • 設定の問題。
  • ネットワーク要求ステータス。

一般的な問題と解決策

ウィンドウが定義されていない

ブラウザSDKを使用する前に、必ずブラウザ環境を確認してください。

typescript
if (typeof window !== "undefined") {
  // Browser-only code
}

重複するイベント

Reactフックを使用してSDKを一度だけ初期化することを確認してください:

typescript
useEffect(() => {
  // Initialization code
}, []); // Empty dependency array

ユーザーコンテキストがありません

認証後にユーザーIDを設定し、ログアウト時にそれをクリアします。

typescript
// After auth
amplitude.setUserId(userId);
// On logout
amplitude.reset();

その他のリソース

Was this helpful?