본문으로 건너뛰기

JavaScript SDK 가이드

1. 설치

SOLAPI CRM SDK는 CDN과 NPM 두 가지 방식으로 설치할 수 있습니다. 번들 크기는 gzip 압축 시 약 2.3KB로 매우 가볍습니다.

CDN 방식 (권장)

<!-- SOLAPI CRM SDK -->
<script src="https://cdn.solapi.com/sdk/crm-sdk/stable/solapi-crm.min.js"></script>
<script>
SolapiCRM.init({
trackingKey: 'tk_live_xxxxxxxxxxxxxxxx',
entityId: 'CRMRC1_contacts',
autoPageView: true
});
</script>

NPM 방식

# NPM
npm install @solapi/crm-browser

# Yarn
yarn add @solapi/crm-browser

# PNPM
pnpm add @solapi/crm-browser
import SolapiCRM from '@solapi/crm-browser';

SolapiCRM.init({
trackingKey: 'tk_live_xxxxxxxxxxxxxxxx',
entityId: 'CRMRC1_contacts',
autoPageView: true
});

2. 초기화 — init(config)

SDK를 사용하려면 먼저 init() 메서드로 초기화해야 합니다.

설정 옵션

파라미터타입기본값설명
trackingKey
String
(필수)
추적 키. 형식: tk_live_xxx 또는 tk_test_xxx
entityId
String
(선택)
기본 개체 ID
endpoint
String
/api/crm/v1/track
API 엔드포인트 URL
autoPageView
Boolean
false
페이지뷰 자동 추적 활성화
batchSize
Number
10
한 번에 전송할 이벤트 수
flushInterval
Number
10000
이벤트 전송 주기 (밀리초)
maxQueueSize
Number
100
큐에 보관할 최대 이벤트 수
debug
Boolean
false
디버그 로그 활성화

전체 설정 예시

SolapiCRM.init({
// 필수: 추적 키
trackingKey: 'tk_live_abc123xyz',

// 권장: 기본 개체 ID
entityId: 'CRMRC1_contacts',

// 선택: 페이지뷰 자동 추적
autoPageView: true,

// 선택: 배치 설정
batchSize: 20,
flushInterval: 5000,
maxQueueSize: 200,

// 선택: 디버그 모드 (개발 환경에서만)
debug: process.env.NODE_ENV === 'development'
});
참고

프로덕션 환경에서는 debug: false로 설정하고, batchSizeflushInterval을 조정하여 네트워크 트래픽을 최적화하세요.

3. 이벤트 추적 — track(eventType, properties?, options?)

사용자 행동을 추적하여 CRM 레코드에 연결합니다. 이벤트는 큐에 저장되었다가 배치로 전송됩니다.

파라미터

파라미터타입설명
eventType
String
이벤트 타입 (예: PURCHASE, SIGNUP, CLICK)
properties
Object
이벤트 속성
options.category
String
이벤트 카테고리
options.label
String
이벤트 레이블
options.value
Number
이벤트 값
options.recordId
String
특정 레코드 ID

기본 이벤트 추적

// 단순 이벤트
SolapiCRM.track('SIGNUP');

// 버튼 클릭 이벤트
document.getElementById('cta-button').addEventListener('click', () => {
SolapiCRM.track('BUTTON_CLICK', {
buttonId: 'cta-button',
buttonText: '무료로 시작하기',
page: window.location.pathname
});
});

속성과 함께 추적

// 구매 이벤트 with 상세 속성
SolapiCRM.track('PURCHASE', {
productId: 'PROD_123',
productName: '나이키 에어맥스',
category: '신발',
quantity: 1,
price: 159000,
currency: 'KRW',
discount: 10000
}, {
category: 'ecommerce',
label: 'summer_sale_2026',
value: 149000
});

특정 레코드에 연결

SolapiCRM.track('PREMIUM_UPGRADE', {
plan: 'Enterprise',
billingCycle: 'annual',
amount: 2400000
}, {
recordId: 'CRMRC1_user_xyz123',
category: 'subscription',
value: 2400000
});

배치 처리 동작

이벤트는 다음 조건 중 하나가 충족될 때 서버로 전송됩니다:

  • 큐 크기: batchSize에 도달하면 자동 전송 (기본값: 10개)
  • 시간 간격: flushInterval 시간이 지나면 전송 (기본값: 10초)
  • 탭 닫기: 브라우저 탭이 닫히거나 페이지를 떠날 때 visibilitychange 이벤트로 자동 전송
  • 재시도: 네트워크 오류 시 최대 3회까지 재시도 (지수 백오프)
  • 큐 오버플로: maxQueueSize를 초과하면 가장 오래된 이벤트부터 삭제
경고

이벤트가 큐에 저장되므로 즉시 서버에 전송되지 않습니다. 실시간 처리가 필요한 경우 SolapiCRM.flush()를 호출하여 강제로 전송하세요.

4. 페이지뷰 추적 — trackPageView()

수동 페이지뷰 추적

// 페이지가 로드될 때
SolapiCRM.trackPageView();

// React Router 예시
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function App() {
const location = useLocation();

useEffect(() => {
SolapiCRM.trackPageView();
}, [location]);

return <div>...</div>;
}

자동 페이지뷰 추적 (권장)

autoPageView: true로 초기화하면 SDK가 자동으로 페이지뷰를 추적합니다. SPA 프레임워크(React, Vue, Angular)에서도 별도 코드 없이 모든 라우팅이 자동 추적됩니다.

자동 감지 이벤트:

  • history.pushState: React Router, Vue Router 등의 라우팅
  • history.replaceState: URL 변경 없이 상태만 변경하는 경우
  • popstate: 브라우저 뒤로 가기/앞으로 가기

자동 수집 속성

속성설명예시
url
전체 URL
https://example.com/products
path
경로
/products
title
페이지 제목
Products - MyShop
referrer
이전 페이지
https://google.com

5. 사용자 식별 — identify(recordId, traits?)

로그인한 사용자를 CRM 레코드에 연결합니다. 익명 사용자의 이벤트를 알려진 레코드로 병합하는 핵심 기능입니다.

기본 사용법

// 로그인 시 — 레코드 ID만 전달
SolapiCRM.identify('CRMRC1_user_xyz123');

// 이후 이벤트는 자동으로 이 레코드에 연결됨
SolapiCRM.track('VIEW_DASHBOARD');

속성과 함께 식별

SolapiCRM.identify('CRMRC1_user_xyz123', {
name: '홍길동',
email: 'hong@example.com',
phone: '01012345678',
plan: 'premium',
lastLogin: new Date().toISOString()
});

익명 사용자 → 알려진 사용자 전환 흐름

  1. 첫 방문 (익명 상태): SDK가 자동으로 익명 ID를 생성합니다 (anon_1234567890abcdef)
  2. 익명 이벤트 수집: 로그인 전 이벤트는 익명 ID로 추적됩니다
  3. 사용자 로그인: identify()를 호출하여 레코드 ID와 연결합니다
  4. 서버 측 이벤트 병합: 서버가 자동으로 익명 ID의 모든 이벤트를 알려진 레코드로 병합합니다
  5. 이후 이벤트: 모든 이벤트가 알려진 레코드에 직접 연결됩니다
참고

익명 ID는 로컬스토리지에 저장되어 브라우저를 닫아도 유지됩니다. 사용자가 로그인하지 않아도 여러 세션에 걸쳐 행동을 추적할 수 있습니다.

6. 레코드 생성 — createRecord(data)

클라이언트에서 직접 새로운 CRM 레코드를 생성할 수 있습니다.

파라미터

파라미터타입설명
entityId
String
개체 ID (선택, 없으면 init()의 기본값 사용)
name
String
레코드 이름 (필수)
data
Object
레코드 속성 (선택)
tags
String[]
태그 목록 (선택)
// 회원가입 폼 제출 시
async function handleSignup(formData) {
try {
const record = await SolapiCRM.createRecord({
entityId: 'CRMRC1_contacts',
name: formData.name,
data: {
email: formData.email,
phone: formData.phone,
company: formData.company,
source: 'website_signup'
},
tags: ['new_user', 'trial']
});

console.log('Created record:', record.recordId);
SolapiCRM.identify(record.recordId);
} catch (error) {
console.error('Failed to create record:', error);
}
}
경고

레코드 생성 기능을 사용하려면 추적 키에 createRecords 권한이 활성화되어 있어야 합니다.

7. 슈퍼 프로퍼티 — register() / registerOnce() / unregister()

슈퍼 프로퍼티는 모든 track() 호출에 자동으로 포함되는 전역 속성입니다.

register(properties) — 전역 속성 등록

SolapiCRM.register({
plan: 'premium',
region: 'ko-KR',
appVersion: '2.1.0'
});

// 이후 모든 track()에 자동 포함됨
SolapiCRM.track('VIEW_PAGE');
// → properties: { plan: 'premium', region: 'ko-KR', appVersion: '2.1.0' }

registerOnce(properties) — 한 번만 등록

이미 존재하는 속성은 덮어쓰지 않습니다. 첫 방문 시점의 정보를 보존하는 데 유용합니다.

SolapiCRM.registerOnce({
initialLandingPage: window.location.href,
initialReferrer: document.referrer,
firstVisit: new Date().toISOString()
});

unregister(propertyName) — 속성 제거

SolapiCRM.unregister('plan');

8. 프라이버시 제어

GDPR, CCPA 등의 개인정보 보호 규정을 준수하기 위한 추적 거부 기능을 제공합니다.

// 추적 거부
SolapiCRM.optOutTracking();

// 추적 허용 (다시 활성화)
SolapiCRM.optInTracking();

// 추적 거부 상태 확인
if (SolapiCRM.hasOptedOut()) {
console.log('사용자가 추적을 거부했습니다.');
}
경고

EU 지역 사용자에게는 추적 시작 전에 명시적인 동의를 받아야 합니다. 기본적으로 optOutTracking() 상태로 시작하고, 사용자가 동의한 후 optInTracking()을 호출하세요.

9. 세션 관리

reset() — 세션 초기화

새로운 익명 ID를 생성하고 모든 슈퍼 프로퍼티를 초기화합니다. 로그아웃 시 사용하세요.

function handleLogout() {
SolapiCRM.reset();
window.location.href = '/login';
}

flush() — 이벤트 즉시 전송

큐에 있는 모든 이벤트를 즉시 서버로 전송합니다.

// 구매 완료 후 즉시 전송
SolapiCRM.track('PURCHASE', { orderId: 'ORD_123', amount: 159000 });
await SolapiCRM.flush();
window.location.href = '/order-complete';

destroy() — SDK 완전 정리

SDK를 완전히 정리합니다. 이벤트 전송, 타이머 정지, History API 복원, 이벤트 리스너 제거 등 모든 작업을 수행합니다.

await SolapiCRM.destroy();

10. 보안 설정

허용 도메인 (Allowed Domains)

패턴허용되는 도메인
example.com
example.com만 허용
*.example.com
모든 서브도메인
localhost:3000
로컬 개발 환경
설정 안 함
모든 도메인 허용

권한 설정

  • trackEvents: 이벤트 추적 (track(), trackPageView(), identify()) 허용
  • createRecords: 레코드 생성 (createRecord()) 허용

환경별 키 분리

const trackingKey = process.env.NODE_ENV === 'production'
? 'tk_live_production_key'
: 'tk_test_development_key';

SolapiCRM.init({
trackingKey,
entityId: 'CRMRC1_contacts',
debug: process.env.NODE_ENV !== 'production'
});
경고

추적 키 (tk_live_xxx)와 SOLAPI API 키 (NCSxxx...)는 다릅니다. API 키는 절대 클라이언트 코드에 포함하면 안 됩니다.

11. 트러블슈팅

문제원인해결
SolapiCRM is not defined
CDN 스크립트 미로드
CDN URL 확인, 스크립트 순서 확인
이벤트 미수집
init() 미호출 또는 키 오류
debug: true로 로그 확인
401 Unauthorized
추적 키 무효/폐기
키 활성 상태 확인, 새 키 생성
403 Forbidden
도메인 미허용
허용 도메인 목록 확인
SPA 페이지뷰 미수집
autoPageView 비활성
autoPageView: true 설정
이벤트 중복 전송
init() 중복 호출
앱에서 한 번만 호출

디버그 모드 활성화

SolapiCRM.init({
trackingKey: 'tk_test_xxx',
entityId: 'CRMRC1_contacts',
debug: true
});

// 콘솔 출력 예시:
// [SolapiCRM] Initialized with trackingKey: tk_test_***
// [SolapiCRM] Track event: BUTTON_CLICK
// [SolapiCRM] Flushing 1 events...
// [SolapiCRM] Events sent successfully

12. FAQ

Q: 추적 키를 클라이언트 코드에 노출해도 안전한가요? 네, 안전합니다. 추적 키는 쓰기 전용이며, 허용 도메인 검증과 권한 제한으로 보호됩니다.

Q: 여러 개체(Entity)에 이벤트를 추적할 수 있나요? 네, init()에서 기본 개체를 설정하고, track() 호출 시 entityId 옵션으로 다른 개체를 지정할 수 있습니다.

Q: 이벤트가 실시간으로 전송되나요? 아니요, 이벤트는 배치로 전송됩니다. 실시간 전송이 필요한 경우 SolapiCRM.flush()를 호출하세요.

Q: 익명 사용자의 이벤트는 얼마나 보관되나요? 90일간 보관됩니다. 90일 내에 identify()를 호출하면 알려진 레코드로 병합됩니다.

Q: 모바일 앱에서도 사용할 수 있나요? 현재 SDK는 웹 브라우저 전용입니다. 모바일 앱에서는 REST API를 직접 호출하세요.

Q: 이벤트 이름 규칙이 있나요? 공식 규칙은 없지만 대문자 + 언더스코어를 권장합니다. (예: BUTTON_CLICK, VIEW_PRODUCT, ADD_TO_CART)