광고 트래킹 개요
레이니는 홈페이지·예약·CRM이 한 시스템 안에 묶여 있기 때문에, 광고로 유입된 방문자가 홈페이지에서 예약까지 이어지는 전체 흐름의 데이터가 한 곳에 남습니다. 같은 데이터를 메타·구글 광고 쪽으로 흘려보내면 광고 플랫폼이 이걸 재료 삼아 "예약할 가능성이 높은 사람"을 찾아주기 시작합니다.
그래서 레이니는 별도 트래킹 도구를 붙이지 않아도 광고 트래킹을 기본 기능으로 지원합니다. 홈페이지에서 발생한 예약·채팅 이벤트, CRM에 쌓이는 고객 데이터가 메타 픽셀·CAPI, 구글 애즈, GA4로 자동 전송되고, 이 데이터가 광고 캠페인의 최적화 신호와 리타기팅 오디언스로 사용됩니다.
"이번 달 광고비 300만 원 썼는데 예약이 몇 건이나 됐는가"에 답할 수 있게 되는 것도, 어떤 광고 채널이 실제로 예약을 만들어내는지 비교할 수 있게 되는 것도 같은 흐름에서 나옵니다. 이 문서에서는 레이니가 어떤 원리로 트래킹을 구성하고, 어떤 데이터를 어디로 보내는지를 차례대로 정리합니다.
광고 트래킹이란
광고 트래킹은 "어떤 광고를 보고 클릭한 사람이 실제로 예약했는지" 기록하는 것입니다.
예를 들어 이런 상황을 추적합니다.
- 구글에서 "강남 피부과 콜라겐" 검색 → 광고 클릭 → 홈페이지 방문 → 예약 폼 제출
- 인스타그램 광고 → 클릭 → 홈페이지 방문 → 채팅 문의
이 흐름이 기록되면, 구글 광고와 인스타그램 광고 중 어디서 예약이 더 많이 들어오는지 볼 수 있습니다. 효과 없는 광고는 줄이고, 효과 있는 광고에 예산을 더 넣을 수 있습니다.
왜 필요한가
트래킹 없이 광고를 운영하면 이런 일이 생깁니다.
- 광고비는 나가는데 어떤 광고가 예약을 만드는지 모름
- 광고 효과가 없어 보여서 중단했는데, 사실 그 광고가 가장 좋은 광고였음
- 성과가 안 나오는 광고에 계속 돈을 쏟아부음
반대로 트래킹이 제대로 되면 이렇게 됩니다.
- "구글 광고에서 이번 달 예약 12건, 인스타 광고에서 3건"처럼 데이터로 판단할 수 있습니다
- 구글에 예산을 더 넣으면 예약이 늘어날 가능성이 높다는 걸 알 수 있습니다
- 광고 플랫폼이 "예약할 가능성 높은 사람"에게 자동으로 광고를 더 보여줍니다
레이니가 해주는 것
픽셀 코드 한 줄만 설치한 셋업에서는 스마트폰 사파리나 광고 차단기를 쓰는 환자의 예약이 기록되지 않습니다. 실제로 예약의 30~40%가 이렇게 사라집니다.
레이니는 다르게 작동합니다. 도메인 연결 한 번이면 아래가 모두 자동으로 세팅됩니다.
- Google Ads 계정 자동 생성 및 전환 추적 설정
- Google Analytics 4 연결
- Meta(인스타그램/페이스북) 픽셀 및 광고 계정 연결
- 네이버, 구글 검색 등록
직접 광고 플랫폼에 로그인해서 설정할 필요가 없습니다.
자동으로 생성되는 것들
커스텀 도메인 DNS 인증이 완료되면, 다음이 모두 자동으로 프로비저닝됩니다.
| 구성 요소 | 설명 | 용도 |
|---|---|---|
| Google Analytics 4 | GA4 속성 + 웹 데이터 스트림 | 방문자 분석, 행동 추적 |
| Google Ads 계정 | MCC 하위 고객 계정 | 광고 캠페인 관리 |
| Google Ads 전환 액션 | Lead + Chat 전환 (35,000원 / 5,000원 가치) | 광고 입찰 최적화 |
| Google Ads Enhanced Conversions for Leads | 해시된 이메일·전화 자동 업로드 | iOS·ITP·광고 차단기 우회 |
| GA4 ↔ Google Ads 연결 | 속성 간 데이터 공유 | 리마케팅 잠재고객 |
| Meta Ads 계정 | Business Manager 하위 계정 | Meta 광고 캠페인 |
| Meta Pixel | 브라우저 측 이벤트 추적 + custom_data | PageView, 리타게팅, 페이지/소스별 전환 분리 |
| Meta CAPI | 서버 측 전환 API + 8개 해시 PII 필드 | Lead 이벤트 (서버 전송), EMQ 7+ 달성 |
| 고객 행 자동 지오 강화 | Vercel 헤더 → DB 컬럼 → CRM 사이드바 | 운영자가 환자 사는 곳 묻지 않아도 됨 |
| Google Search Console | 사이트 소유권 인증 | SEO 인덱싱, 검색 성과 |
전체 데이터 흐름
전체 과정을 한 그림에 담으면 요소가 너무 많아 읽기 어렵습니다. 세 단계로 나눠서 따라가면 됩니다.
1단계 — 광고 클릭 → 랜딩 페이지 진입
광고에서 들어온 방문자가 누구로부터 왔는지를 표시해 두는 단계입니다. 클릭 ID가 쿠키에, UTM이 세션 스토리지에 저장되고, 동시에 GA4·Meta Pixel에 페이지뷰가 한 번씩 찍힙니다.
2단계 — 예약·채팅 발생 → 클라이언트에서 4방향 전송
방문자가 예약 폼을 제출하거나 채팅을 시작하면 이벤트가 트리거됩니다. 같은 이벤트 ID를 달고 네 방향으로 한 번에 나갑니다.
같은 eventID를 달고 나가기 때문에 GA4·Google Ads·Meta Pixel·서버 API 사이에서 자동 중복 제거가 됩니다.
3단계 — 서버 측 처리 → 광고 플랫폼·CRM 동기화
위 2단계의 서버 API 호출이 받는 쪽에서 일어나는 일입니다. 해싱된 개인정보를 광고 플랫폼으로 보내고, Vercel이 넘겨주는 지역 정보를 고객 레코드에 붙여 대시보드 사이드바에서 보이도록 합니다.
세 단계를 합치면, 한 건의 예약이 GA4 · Google Ads 클라이언트 · Google Ads 서버 · Meta Pixel · Meta CAPI · CRM 사이드바까지 총 여섯 곳에 같은 이벤트 ID로 동기화됩니다.
추적하는 행동 2가지
레이니는 2가지 행동을 전환으로 추적합니다.
| 전환 | 언제 기록되나 | 의미 |
|---|---|---|
| 예약(Lead) | 예약 폼 제출 시 | 예약 의사 있는 환자 |
| 채팅(Chat) | 채팅 위젯을 열 때 | 관심 있어서 문의하는 환자 |
두 가지를 구분해서 보면, "예약까지 간 광고"와 "관심만 끈 광고"를 따로 분석할 수 있습니다.
트래킹 파이프라인 아키텍처
레이니의 트래킹 파이프라인은 @workspace/tracking 패키지로 구현되어, 모든 테넌트 랜딩 페이지에서 동일한 방식으로 동작합니다. 브라우저 쪽과 서버 쪽을 나눠 보면 구조가 더 명확하게 보입니다.
브라우저 측 — 클라이언트 전송
TrackingProvider가 전역 컨텍스트를 깔아 주고, 각 컴포넌트는 useTracking 훅으로 이벤트를 발화합니다. 같은 훅 호출 한 번이 GA4·Google Ads·Meta Pixel로 동시에 나가고, 서버 API로도 같은 이벤트를 전달합니다.
서버 측 — API 라우트에서 마무리
클라이언트에서 넘어온 이벤트를 서버에서 받아 세 방향으로 분기합니다. Vercel이 붙여 준 지역 정보를 고객 레코드에 채워 넣고, 해싱된 개인정보를 Google Ads API와 Meta CAPI로 흘려 보냅니다.
두 파이프라인을 합치면 한 건의 폼 제출이 GA4·Google Ads 클라이언트·Google Ads 서버·Meta Pixel·Meta CAPI·CRM 사이드바까지 여섯 곳에 동기화됩니다. 모두 같은 eventID로 중복 제거되고, 같은 고객 UUID(external_id)로 식별됩니다.
Consent Mode v2
모든 Google/Meta 스크립트가 로드되기 전에 동의 기본값이 설정됩니다.
<head>
1. consent-defaults (beforeInteractive)
→ gtag('consent', 'default', { ad_storage: 'granted', ... })
2. GA4 gtag.js (afterInteractive)
3. Google Ads config (afterInteractive)
4. Meta Pixel fbevents.js (afterInteractive)
</head>| 동의 카테고리 | 기본값 | 설명 |
|---|---|---|
ad_storage | granted | 광고 쿠키 |
analytics_storage | granted | 분석 쿠키 |
ad_user_data | granted | 광고 목적 사용자 데이터 전송 |
ad_personalization | granted | 리마케팅/개인화 광고 |
한국 시장은 GDPR 적용 대상이 아니므로 기본값을
granted로 설정합니다. EU 방문자를 대상으로 할 경우 지역별 기본값을denied로 변경할 수 있습니다.
클릭 ID 캡처
사용자가 광고를 클릭하여 랜딩 페이지에 도착하면, URL의 클릭 ID 파라미터가 자동으로 캡처됩니다.
| 파라미터 | 저장 위치 | 유효 기간 | 용도 |
|---|---|---|---|
gclid | 쿠키 _lny_gclid | 90일 | Google Ads 클릭 어트리뷰션 |
wbraid | 쿠키 _lny_wbraid | 90일 | iOS 앱→웹 전환 추적 |
gbraid | 쿠키 _lny_gbraid | 90일 | 웹→iOS 앱 전환 추적 |
fbclid | sessionStorage | 세션 | Meta 광고 클릭 식별 |
utm_source, utm_medium, utm_campaign, utm_content, utm_term도 sessionStorage에 저장되어 세션 내 페이지 이동 후에도 유지됩니다.
이벤트 추적
자동 추적 이벤트
| 이벤트 | 트리거 | GA4 | Meta Pixel |
|---|---|---|---|
page_view | 페이지 로드 | gtag.js 자동 | fbq('track', 'PageView') |
lny_cta_click | CTA 버튼 클릭 | gtag('event', ...) | - |
lny_lead | 예약/문의 폼 제출 | gtag('event', ...) | fbq('track', 'Lead') |
lny_chat | 채팅 시작 | gtag('event', ...) | fbq('track', 'Lead') |
conversion | 폼 제출 / 채팅 | gtag('event', 'conversion') | - |
모든 커스텀 이벤트에는 다음 파라미터가 포함됩니다:
{
"event_id": "UUID (이벤트 중복 제거용)",
"tenant_id": "조직 slug"
}TrackingProvider
TrackingProvider는 RSC 레이아웃에서 조직의 integrations 데이터를 기반으로 TrackingConfig를 생성하고, 하위 클라이언트 컴포넌트에 컨텍스트를 제공합니다.
[RSC Layout]
→ org.integrations (Supabase)
→ buildTrackingConfig()
→ TrackingProvider (client context)
├── ConsentModeScripts
├── CtaProvider (CTA 버튼 클릭 추적)
├── ReservationDialog (폼 제출 추적)
├── ChatPopover (채팅 시작 추적)
└── AnalyticsScripts (GA4/Ads/Pixel 스크립트)useTracking() Hook
const tracking = useTracking();
// 일반 이벤트 추적
tracking.trackEvent("lny_cta_click", { cta_type: "reservation" });
// 전환 추적 — full 강화 페이로드
tracking.trackConversion("lead", {
phone: value.customer_phone,
email: detectedEmail,
displayName: value.customer_name,
externalId: submission.id, // 폼 upsert가 반환한 customer DB UUID
customData: {
source: "reservation_form",
contentName: document.title,
contentCategory: "product/collagen-touch",
locale: "ko",
referenceId: submission.id,
},
});trackConversion()은 한 번의 호출로 다음을 모두 실행합니다:
gtag('event', 'lny_lead', { ... })— GA4 커스텀 이벤트 (tenant_id,event_id,source,reference_id포함)gtag('event', 'conversion', { send_to: 'AW-XXX/label', value, currency, transaction_id })— Google Ads 전환fbq('track', 'Lead', { content_name, content_category, source, locale, reference_id }, { eventID })— Meta Pixel with custom dataPOST /api/track/conversion { userData, customData }— 서버 측 전환 (Google Ads API + Meta CAPI + 고객 행 지오 동기화)
같은 eventID가 4개 호출 모두에 사용되어 자동 중복 제거됩니다.
중복 호출 가드:
ChatPopover의onOpenChange는 shadcnSheet의 애니메이션 중 동기적으로 두 번 호출될 수 있습니다.useState기반 가드 (if (!chatOpen))는 두 호출 모두 stale state를 보기 때문에 작동하지 않습니다. 레이니는useReflatch로 chat open당 정확히 한 번만trackConversion이 발화되도록 보장합니다.
스크립트 로딩 전략
| 스크립트 | Next.js Strategy | 설명 |
|---|---|---|
| Consent 기본값 | beforeInteractive | 다른 모든 스크립트보다 먼저 로드 |
GA4 gtag.js | afterInteractive | 페이지 하이드레이션 후 로드 |
| Google Ads config | afterInteractive | GA4와 함께 config 전송 |
Meta Pixel fbevents.js | afterInteractive | 페이지 하이드레이션 후 로드 |
| Tenant context | afterInteractive | dataLayer에 tenant_id push |
모든 스크립트는 조직의 integrations에 해당 ID가 존재할 때만 삽입됩니다. 연동이 설정되지 않은 조직의 랜딩 페이지에는 불필요한 스크립트가 로드되지 않습니다.
이 시스템이 중요한 이유
광고 비용 최적화
Google Ads와 Meta Ads의 자동 입찰(Smart Bidding)은 전환 데이터의 품질과 양에 따라 성능이 결정됩니다. 레이니는 클라이언트 + 서버 양쪽에서 전환을 전송하여 광고 플랫폼이 받는 신호의 양을 늘립니다.
광고 차단기 대응
브라우저 광고 차단기가 클라이언트 측 추적을 차단해도, 서버 측 전환 API(Meta CAPI, Google Ads API)는 영향을 받지 않습니다. 전환 데이터 손실을 줄여줍니다.
크로스 디바이스 어트리뷰션
Enhanced Conversions(향상된 전환)를 통해 전화번호를 SHA-256으로 해싱하여 서버에서 전송합니다. Google과 Meta는 이 데이터를 로그인된 사용자 정보와 매칭하여 기기 간 전환을 추적합니다.
관련 문서
- 자동으로 설정되는 것들 — 도메인 연결 후 자동 세팅 전체 목록
- 전환 추적 — 어떤 광고가 예약을 만들었는지 확인하는 법
- 검색 엔진 연동 — 구글/네이버 검색 등록