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+)
컴포넌트를 가져와서 루트 레이아웃에 추가합니다.
// app/layout.tsx
import { Amplitude } from "@/amplitude";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<Amplitude />
<body>
{children}
</body>
</html>
);
}
페이지 라우터(레거시)
Pages 라우터의 경우 _app.tsx에서 Amplitude를 초기화하십시오.
// pages/_app.tsx
import '@/amplitude';
import type { AppProps } from 'next/app';
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default MyApp;
구성 요소에서 Amplitude 사용하기
// 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를 사용하십시오.
npm install @amplitude/analytics-node
서버측 Amplitude 클라이언트를 생성합니다.
// 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 경로에 추가합니다.
// 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 });
}
// 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 키를 환경 변수에 저장하십시오:
# .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.
},
},
});
자동 캡처에서 다루지 않는 비즈니스별 이벤트의 경우:
// 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 미들웨어를 사용하여 서버측 이벤트를 추적합니다:
// 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 로그를 확인하십시오.
- 이벤트 트래킹 확인.
- 구성 문제.
- 네트워크 요청 상태.
일반적인 문제 및 해결책
Window가 정의되지 않았습니다.
브라우저 SDK를 사용하기 전에 항상 브라우저 환경을 확인하십시오.
if (typeof window !== "undefined") {
// Browser-only code
}
중복 이벤트
React hooks를 사용하여 SDK를 한 번 초기화해야 합니다.
useEffect(() => {
// Initialization code
}, []); // Empty dependency array
사용자 컨텍스트 누락
인증 후 사용자 ID를 설정하고 로그아웃 시 이를 지웁니다.
// After auth
amplitude.setUserId(userId);
// On logout
amplitude.reset();
추가 리소스
이 내용이 도움이 되었나요?