개요
INFO: 웹 어트리뷰션은 엔터프라이즈 기능입니다. 계정에 이 기능을 활성화하려면 고객 성공 매니저에게 문의하십시오.
이 가이드는 Google 태그 관리자 (GTM)를 사용하여 Singular 웹 SDK를 구현하는 방법을 설명합니다. 이 방법은 웹사이트 코드에 직접 접근할 수 없는 팀이나 GTM을 통해 추적을 관리하려는 팀에 이상적입니다.
중요! 동일 사이트에서 GTM과 네이티브 자바Script 구현을 동시에 사용하지 마십시오. 중복 추적 및 부풀려진 이벤트 수를 방지하려면 하나의 방법만 선택하십시오. Singular는 자동으로 이벤트 중복 제거를 수행하지 않습니다.
- 네이티브 자바Script와 Google 태그 관리자 방식을 동시에 구현하지 마십시오. 중복 추적을 방지하려면 한 가지 방법만 선택하십시오.
- Singular 웹 SDK는 사용자의 브라우저에서 클라이언트 측으로 실행되도록 설계되었습니다. 정상적인 작동을 위해서는 localStorage 및 DOM(Document Object Model) 과 같은 브라우저 기능에 대한 접근이 필요합니다. 서버 측 (예: Next.js SSR 또는 node.js를 통한)에서 SDK를 실행하려고 시도하지 마십시오. 서버 환경은 브라우저 API에 대한 접근을 제공하지 않으므로 추적 오류가 발생합니다.
필수 조건
시작하기 전에 다음을 준비하십시오:
-
SDK 키 및 SDK 시크릿:
- 찾는 방법: Singular 계정에 로그인한 후 개발자 도구 > SDK 연동 > SDK 키로 이동하세요.
-
제품 ID:
-
정의: 웹사이트의 고유 이름으로, 역방향 DNS 형식(예:
com.website-name)을 사용하는 것이 이상적입니다. - 중요성: 이 ID는 웹사이트를 Singular 내 앱으로 연결하며, Singular의 앱 페이지에 기재된 웹 앱 bundleID와 반드시 일치해야 합니다.
-
정의: 웹사이트의 고유 이름으로, 역방향 DNS 형식(예:
- 귀하의 사이트에Google 태그 관리자가설정되어 있습니다.
- GTM에서 웹사이트 태그, 트리거 및 변수를 편집할 수 있는 권한이 필요합니다. 사용자 정의에 따라 맞춤 태그 생성 방법과 태그 순차 설정 방법을 알아야 할 수 있습니다.
- Google 태그 관리자에 변경 사항을 게시할 권한이 없는 경우, 테스트 후 변경 사항을 게시해 줄 사람을 요청해야 합니다.
- GTM에서 컨테이너 및 태그를 미리 보고 디버깅하는 방법에 대한 지식.
- 추적하고자 하는 이벤트 목록. 아이디어를 얻으려면 당사의 Singular 표준 이벤트: 전체 목록 및 업종별 추천 이벤트를 참조하십시오.
구현 단계
1단계: Singular 웹 추적 템플릿을 GTM 컨테이너에 추가하기
- Google 태그 관리자 계정에 로그인하여 웹사이트의 컨테이너를 선택하세요.
- 태그 > 새로 만들기로 이동합니다.
- 태그 이름 지정: "Singular 초기화 태그"
- 태그 구성 상자를 클릭하여 태그 설정을 시작합니다.
- 태그 유형 선택 : "커뮤니티 템플릿 갤러리에서 더 많은 태그 유형 찾기"를 선택합니다.
- "Singular" 를 검색하고 "Singular 웹 추적"을 선택하세요. "작업 공간에 추가" 버튼을 클릭하세요.
2단계: SDK 초기화
-
다음과 같이 양식 필드를 완성하세요:
- 추적 유형 을 초기화로 설정하세요
- Api 키 필드에 실제 SDK 키를 입력하세요
- 실제 SDK 시크릿을 시크릿 필드에 입력하세요. 필드
-
실제 제품 ID를 입력하세요. 형식은
com.website-name과 같아야 하며, Singular 플랫폼의 앱 페이지에 있는 번들 ID 값과 일치해야 합니다.팁! 테스트용으로 별도의 제품 ID(예:
com.website-name.dev)를 사용하세요. 본격적인 서비스 시작 전에는 반드시 업데이트해야 합니다. 이렇게 하면 Singular 리포팅에서 테스트 데이터와 본격 서비스 앱 데이터를 완전히 분리할 수 있습니다. -
선택 사항:
- 로그 수준: SDK 디버그 로깅을 콘솔에 출력하도록 구성합니다 . 기본값은 없음입니다.
- 이벤트 중복제거
- 글로벌 속성 설정
- 스마트 배너 활성화 (엔터프라이즈 전용)
- 고객 사용자 ID 설정
- 세션 시간 초과: 사용자가 비활성 상태인 경우 SDK가 새 세션을 생성하기까지의 시간 . Singular는 사용자 세션을 전송하여 사용자 유지율을 계산하고 리인게이지먼트 기여도 측정을 가능하게 합니다. 기본값은 30분입니다.
- 크로스 서브도메인 추적
- 이 태그가 작동하도록 트리거를 구성하려면 트리거 설정을 선택하십시오.
- 새로 만들기를 선택하고 트리거 이름을"Singular Init Trigger" 로 지정하세요.
- 트리거 구성을 클릭하고 "페이지 뷰 - 창 로드됨"을 선택한 후 "저장"을 클릭하세요.
- 태그를 저장하려면 "저장"을 다시 클릭하세요.
-
태그 페이지에서 "미리 보기"를 클릭하고
Singular
초기화 태그가 트리거되는지 테스트합니다.
성공! 미리보기 콘솔의 '태그 발동' 섹션에 "Singular 초기화 태그"가 표시되면 초기화 태그 설정이 성공적으로 완료된 것입니다.
중요! SPA(Singular 페이지 애플리케이션) 의 경우 , 다른 페이지로 이동할 때마다 페이지 방문 트랙타입을 트리거해야 합니다. 첫 페이지 로드 시 페이지 방문을 호출하지 마십시오. 초기화가 이미 페이지 방문을 보고했기 때문입니다. 해결책 개요
솔루션 개요
- 사용자 정의 JavaScript 변수를 사용하여 첫 페이지 로드인지 감지합니다.
-
2개의 태그 구성:
- "Singular 초기화 태그"(추적 유형 = 초기화) : 초기 페이지 로드 시에만 발동.
- "Singular 페이지 방문 태그"(추적 유형 = 페이지 방문)는 역사 변경 트리거를 사용하여 경로 변경 시마다(초기 로드 제외) 발동됩니다.
- SPA가 경로 변경 시 히스토리 이벤트를 데이터 레이어에 푸시하도록 설정하십시오.
3단계: 이벤트 추적
SDK 초기화 후, 사용자가 웹사이트에서 중요한 행동을 수행할 때 커스텀 이벤트를 추적할 수 있습니다.
중요! Singular는 중복 이벤트를 차단하지 않습니다! 페이지 새로고침이나 중복 발생을 방지하는 보호 장치는 개발자의 책임입니다. 특히 구매 이벤트의 경우 오류가 있는 구매 데이터를 방지하기 위해 중복 제거 방법을 적용하는 것이 권장됩니다. 예시는 아래 "단계 5: 중복 이벤트 방지"를 참조하십시오.
기본 이벤트 추적
단순한 이벤트를 추적하거나 유효한 JSON을 사용하여 사용자 정의 속성을 추가해 이벤트에 대한 추가 컨텍스트를 제공하세요:
-
Singular 웹 추적 템플릿을 사용하여 사용자 정의 이벤트용 새 태그를 생성하세요.
-
이벤트 태그에 이름을 지정하세요.
-
추적 유형 = 사용자 정의 이벤트 선택
-
"이벤트 이름" 필드를 조정하거나 적절한 변수를 설정하세요.
-
"사용자 지정 ID" 필드를 조정하거나 적절한 변수를 설정하세요. 필요 시 "속성"을 조정하여 이벤트에 키/값 쌍을 전달하세요.
-
이벤트에 키/값 쌍을 전달하려면 원하는 경우 "속성"을 조정하십시오.
-
예상된 경우에만 태그가 발동되도록 트리거를 구성하십시오.
-
트리거와 태그를 저장하고 미리보기에서 테스트하세요.
전환 이벤트 추적
전환 이벤트 추적:
-
Singular 웹 추적 템플릿을 사용하여 사용자 정의 이벤트용 새 태그를 생성합니다. 웹 추적
-
전환 이벤트 태그에 이름을 지정하세요.
-
추적 유형 = 전환 이벤트 선택
-
"이벤트 이름" 필드를 조정하거나 적절한 변수를 설정하세요.
-
"사용자 지정 ID" 필드를 조정하거나 적절한 변수를 설정하세요. 필요 시 "속성"을 조정하여 이벤트에 키/값 쌍을 전달하세요.
-
필요 시 "속성"을 조정하여 이벤트에 키/값 쌍을 전달하십시오. 이벤트에 키/값 쌍을 전달하십시오.
-
예상된 시점에만 태그가 발동되도록 적합한 트리거를 구성하십시오.
-
트리거와 태그를 저장하고 미리보기에서 테스트하세요.
구매 이벤트 추적
구매 정보가 포함된 전환 이벤트를 추적하고 추가적인 컨텍스트를 위해 선택적 속성을 추가하세요:
-
Singular 웹 추적 템플릿을 사용하여 사용자 정의 이벤트용 새 태그를 생성하세요.
-
구매 이벤트 태그에 이름을 지정하세요.
-
추적 유형 = 구매 이벤트 선택
-
"이벤트 이름" 필드를 조정하거나 적절한 변수를 설정하세요.
-
"사용자 지정 ID" 필드를 조정하거나 적절한 변수를 설정하세요.
-
"통화" 필드를 조정하거나 적절한 변수를 설정하세요. 구매 통화는 3자리 ISO 4217 통화 코드(예: "USD", "EUR", "INR")로 전달하세요.
-
"구매" 필드를 조정하거나 적절한 변수를 설정하세요. 구매은 명시된 통화로 표시되어야 합니다.
-
이벤트에 키/값 쌍을 전달하려면 원하는 경우 "속성"을 조정하십시오.
-
예상된 시점에만 태그가 발동되도록 트리거를 구성하십시오.
-
트리거와 태그를 저장하고 미리보기에서 테스트하십시오.
일반적인 이벤트 구현 패턴
페이지 로드 이벤트용 GTM 트리거 생성
Singular 웹 SDK를 Google 태그 관리자와 함께 구현하려면 페이지 로드 시 발동되는 페이지 로드 트리거를 생성해야 합니다.
빠른 설정: GTM에서 트리거 > 새로 만들기 > 트리거 구성으로 이동하여 트리거 유형으로 "페이지 뷰"를 선택하세요. 대부분의 구현에서는 모든 페이지 로드 시 트리거가 작동하도록 "모든 페이지 뷰"를 선택하세요.
전체 설정 안내: Google 공식 태그 관리자 문서를 참조하세요:
버튼 클릭용 GTM 트리거 생성
Singular 웹 SDK를 통해 Google 태그 관리자로 버튼 사용자 상호작용을 추적하려면 특정 요소를 클릭할 때 발동되는 클릭 트리거를 생성해야 합니다.
빠른 설정: GTM에서 트리거 새 트리거 구성으로 이동하여 모든 페이지 요소(버튼, 링크, 이미지) 클릭을 추적하려면 "모든 요소"를 선택하거나 HTML 앵커 요소만 추적하려면 "링크만"을 선택하세요.
클릭 변수 활성화: 클릭 트리거 생성 전, GTM에서 내장 클릭 변수를 활성화하세요. 변수 구성 내장 변수로 이동하여 "클릭" 항목 아래 모든 옵션을 선택합니다.
특정 요소 타겟팅: 성능 향상을 위해 "모든 클릭" 대신 "일부 클릭"을 사용하고 클릭 ID, 클릭 클래스 또는 클릭 텍스트 기반 조건을 추가하여 특정 버튼을 타겟팅하세요.
전체 설정 안내: Google 공식 태그 관리자 문서를 참조하세요:
양식 제출 이벤트용 GTM 트리거 생성
Google 태그 관리자를 통해 Singular 웹 SDK로 양식 완료를 추적하려면 사용자가 사이트에서 양식을 성공적으로 제출할 때 발동되는 양식 제출 트리거를 생성해야 합니다.
빠른 설정: GTM에서 트리거 새 트리거 구성으로 이동하여 트리거 유형으로 "양식 제출"을 선택하세요. 성공적인 양식 제출 시에만 추적이 발생하도록 "검증 확인"을 활성화하고, 페이지 리디렉션 전에 추적이 가능하도록 2000ms 지연 시간으로 "태그 대기"를 활성화하는 것을 고려하세요.
양식 변수 활성화: 양식 트리거 생성 전, GTM에서 내장 양식 변수를 활성화하세요. 변수 구성 내장 변수로 이동하여 "양식" 아래 모든 옵션을 선택합니다.
성능 최적화: 더 나은 성능을 위해 "모든 양식" 대신 "일부 양식"을 선택하고 양식 제출이 발생하는 특정 양식이나 페이지를 대상으로 하는 조건을 추가하세요.
대체 방법: 최신 AJAX 양식은 표준 양식 제출 트리거와 호환되지 않을 수 있습니다. 내장 트리거가 작동하지 않을 경우, 성공 메시지나 감사 페이지 추적을 위한 요소 가시성 트리거와 같은 대체 추적 방법을 고려하십시오.
전체 설정 안내: Google 공식 태그 관리자 문서를 참조하세요:
4단계: 고객 사용자 ID 설정
Singular SDK 메서드를 사용하여 내부 사용자 ID를 Singular로 전송할 수 있습니다.
참고: Singular의 크로스 디바이스 솔루션을 사용하는 경우 모든 플랫폼에서 사용자 ID를 수집해야 합니다. 참고: 여러 사용자가 Singular 기기를 사용하는 경우 로그인 및 로그아웃 시마다 사용자 ID를 설정 및 해제하는 로그아웃 흐름 구현을 권장합니다.
참고: 여러 사용자가 Singular 기기를 사용하는 경우, 로그인 및 로그아웃 시마다 사용자 ID를 설정하고 해제하는 로그아웃 흐름을 구현하는 것이 좋습니다.
팁! 모바일 SDK에서 사용하는 것과 동일한 고객 사용자 ID를 사용하세요. 이를 통해 크로스 디바이스 어트리뷰션이 가능해지며 플랫폼 전반에 걸친 사용자 행동에 대한 완전한 시각을 제공합니다.
사용자가 로그인하지 않은 상태에서 웹사이트에서 행동을 수행하는 한, 이벤트는 Singular에서 생성한 사용자 ID와 함께 Singular로 전송됩니다. 그러나 사용자가 등록하거나 로그인한 후에는, 웹사이트에서 사용하는 사용자 ID(예: 해시 처리된 이메일 주소)와 함께 이벤트를 Singular로 전송할 수 있습니다.
Singular는 사용자 수준 데이터 내보내기( 애트리뷰션 로그 내보내기 참조)와 내부 BI 포스트백(설정된 경우, 내부 BI 포스트백 구성 참조)에서 사용자 ID를 사용합니다.
사용자 ID를 Singular로 전송하는 방법은 두 가지입니다:
- 권장: 웹사이트가 열릴 때 사용자 ID를 알고 있다면 , SDK 초기화 시 초기화 트랙 유형에서 사용자 ID를 설정하세요. 이렇게 하면 첫 페이지 방문부터 Singular가 사용자 ID를 사용할 수 있습니다. 또는, 인증이 발생한 후 언제든지(일반적으로 인증 후) 트랙 유형 = 로그인의 태그를 트리거할 수 있습니다. 사용자 ID가 사용 가능해지는 즉시 호출하는 것이 좋습니다.
- 또는, 트랙 유형 = 로그인 (Track Type = Login ) 태그를 인증이 발생한 후 등 언제든지 트리거할 수 있습니다. 사용자 ID를 사용할 수 있게 되는 즉시 호출하는 것이 좋습니다. 참고: 이 태그를 호출해도 이벤트는 트리거되지 않습니다. 향후 발생할 모든 이벤트 트리거에 추가될 사용자 ID만 설정합니다!
Singular로 사용자 ID를 설정하려면 "로그인" 추적 유형의 Singular 태그를 추가하세요:
- Google 태그 관리자 계정에서 태그 > 새로 만들기를 클릭하세요.
- 태그 구성 창에서 태그 구성을 클릭하고 태그유형 메뉴에서 "Singular 웹 추적"을 선택합니다.
- 추적 유형에서 "로그인"을 선택합니다.
- 사용자 지정 ID 항목에 사용자 ID를 포함하는 Google 태그 관리자 변수를 입력합니다.
- 트리거링을 클릭하고 트리거링 이벤트를 추가합니다: 사용자 로그인 또는 등록.
- 저장을 클릭합니다.
사용자 ID를 해제하려면 "로그아웃" 추적 유형의 태그를 추가하세요:
- Google 태그 관리자 계정에서 태그 > 새로 만들기를 클릭합니다.
- 태그 구성 창에서 태그 구성을 클릭하고 태그유형 메뉴에서 "Singular 웹 추적"을 선택합니다.
- 추적 유형에서 "로그아웃"을 선택합니다.
- 트리거링을 클릭하고 트리거링 이벤트를 추가합니다: 사용자 로그아웃.
- 저장을 클릭합니다.
참고:
- 사용자 ID는 로그아웃 추적 유형을 사용하여 해제하거나 사용자가 로컬 스토리지를 삭제할 때까지 유지됩니다.
- 웹사이트를 닫거나 새로 고침해도 사용자 ID는 유지됩니다.
- 시크릿 모드와 같은 비공개 모드에서 브라우징하면 브라우저를 닫을 때 로컬 스토리지가 자동으로 삭제되므로 Singular가 사용자 ID를 지속적으로 유지하지 못합니다.
5단계: 이벤트 중복 제거(선택 사항)
Google 태그 관리자(GTM)의 이벤트 중복 제거
중요! GTM 트리거가 짧은 시간 내에 동일한 Singular 이벤트를 여러 번 발생시킬 수 있는 경우(예: 빠른 반복 클릭 또는 동일한 동작에 대한 여러 트리거), Singular의 선택적 이벤트 중복 제거 기능을 활성화하여 중복 내보내기를 자동으로 억제하십시오.
GTM에서 중복이 발생하는 이유
GTM은 동일한 사용자 행동에 대해 태그를 여러 번 평가 및 발동할 수 있습니다(예: 반복되는 트리거 조건 또는 여러 이벤트 리스너). 이로 인해 Singular 이벤트 내보내기가 중복될 수 있습니다.
GTM 중복 제거 방법 (권장)
Singular SDK 이벤트 중복 제거: Singular 웹 SDK GTM 템플릿에서 중복 제거를 활성화하여 구성 가능한 시간 창 내에서 동일한 중복 제거 매개변수와 일치하는 중복 이벤트를 제거합니다.
구현 단계
이벤트 중복 제거 활성화: Singular 웹 SDK 초기화 태그/템플릿에서 이벤트 중복 제거 옵션을 활성화합니다.
시간 창 설정(선택 사항): 두 이벤트를 중복으로 간주하는 최대 시간 창 (밀리초 단위)을 구성합니다(기본값: 1000ms / 1초).
중복 제거 작동 방식
활성화 시 SDK는 다음 매개변수 해시를 사용하여 동일한 이벤트가 시간 창 내에 재발생할 경우 이벤트(페이지 방문 제외)를 억제합니다: EventName, EventProductName, IsRevenueEvent, CustomUserId, GlobalProperties, MatchId, WebUrl(구매 및 사용자 정의 인자 등 이벤트 "추가" 페이로드 포함).
6단계: GTM 구현 테스트
- GTM 미리보기 모드를 열고 웹사이트를 로드합니다.
- 다음 사항을 확인하십시오:
-
SDK가 로드되는지 (
singular-sdk.js로의 네트워크 요청) - 이벤트가 예상대로 트리거되며, 각 액션당 한 번만 발생함
-
singular관련 브라우저 콘솔 오류 없음 -
네트워크 요청이
sdk-api-v1.singular.net로 전송됨
- 브라우저 개발자 도구 네트워크 탭에서 올바른 페이로드가 전송되는지 확인하세요
성공! 네트워크 요청에서 올바른 Singular 이벤트가 표시되고 중복이 없다면 실행 준비 완료!
7단계: 웹-앱 전달 구현
웹-앱 어트리뷰션 전달
Singular 웹 SDK를 사용하여 웹사이트에서 모바일 앱으로의 사용자 여정을 추적하세요. 이를 통해 웹 캠페인에 대한 정확한 모바일 앱 설치 및 리인게이지먼트 어트리뷰션이 가능해집니다. 데스크톱 사용자를 위한 QR 코드 지원 포함, 웹-앱 전달 설정 방법은 다음 단계를 따르세요. 웹-앱 전달 설정 가이드를 참조하여 모바일 웹 어트리뷰션을 위한 Singular 웹 SDK를 구성하세요.
- 모바일 웹 어트리뷰션용 Singular 웹 SDK 구성을 위해 웹사이트-모바일 앱 어트리뷰션 전달 가이드 를따르세요.
-
모바일 웹-앱 추적 방법:
-
앱 열기 태그를 추가하고 앱 열기 또는 설치 버튼 클릭 시 발동 트리거를 설정하세요.
-
앱 실행 태그 설정 시, Singular 링크 관리 페이지에서 모바일 웹-앱 기본 링크를 지정하세요.
-
-
앱 열기 태그를 추가하고 앱 열기 또는 설치 버튼 클릭 시 발동 트리거를 설정하세요.
-
데스크톱 웹-앱 전환 추적:
-
QR 코드 생성기 정리 태그 생성
- GTM에서 태그 > 새로 만들기로 이동하여 사용자 정의 HTML을 선택하세요.
-
코드 추가 위치:
- 선택한 QRCode 라이브러리 삽입
-
다음에서 웹-투-앱 링크를 가져옵니다:
window.singularSdk.buildWebToAppLink(baselink); - 반환된 링크로 QR 코드 생성
- 페이지의 QR코드 이미지를 업데이트하세요.
- 태그 이름 지정: "Singular - QR 코드 생성기 (정리)"
- 트리거 불필요: 정리 태그는 메인 태그의 트리거를 상속합니다
-
Singular 초기화 태그 구성:
- 태그 구성클릭
- 고급 설정 > 태그 순서로이동
- "[Singular 초기화 태그] 실행 후 정리 태그 실행" 선택
- 드롭다운에서 QR 코드 생성기 태그 선택
- 태그를 저장하고 미리보기 모드에서 테스트하세요.
-
QR 코드 생성기 정리 태그 생성
팁! 모바일 인앱 브라우저 웹 뷰(Facebook, Instagram, TikTok 등에서 사용되는 방식)는 사용자가 기기의 기본 브라우저로 이동할 경우 Singular 기기 ID가 변경되어 어트리뷰션에 차질을 빚을 수 있습니다.
이를 방지하려면 각 광고 네트워크에 대해 항상 적절한 Singular 추적 링크 형식을 사용하십시오:
고급 주제
Singular 배너
글로벌 속성 추가
Singular SDK를 사용하면 모든 세션 및 이벤트와 함께 Singular 서버로 전송될 사용자 정의 속성을 정의할 수 있습니다. 이러한 속성은 사용자 정보, 앱 모드/상태 또는 선택한 기타 정보를 나타낼 수 있습니다.
-
유효한 JSON 객체로 최대 5개의 글로벌 속성을 정의할 수 있습니다. 글로벌 속성은 브라우저의
localStorage에 지워질 때까지 저장됩니다. -
각 속성 이름과 값은 최대 200자까지 가능합니다. 이보다 긴 속성 이름이나 값을 전달하면 200자로 잘립니다.
-
글로벌 속성은 Singular의 사용자 수준 이벤트 로그와 포스트백에 반영됩니다.
이제 Google Tag Manager 추적 템플릿 초기화 시 글로벌 속성이 지원됩니다. Singular GTM 초기화 태그 유형에서 속성 JSON 객체를 설정하고 기존 속성 덮어쓰기 여부를 선택하세요.
GTM의 글로벌 속성 태그 유형
초기화 시 글로벌 속성을 설정하려면 초기화 태그 유형을 사용하십시오. 초기화 후 런타임 업데이트에는 전용 글로벌 속성 태그 유형(설정, 가져오기, 해제, 지우기)을 사용하십시오.
초기화 태그 구성
Singular GTM 초기화 태그 유형에서 Global Properties (객체)를 설정하려면 Key및 Value 필드에
변수, 데이터 레이어 값 또는 텍스트를 할당하세요.
필요에 따라 Override (true/false) 필드를
조정하세요. Override 가 false 인 경우 기존 속성은 변경되지 않으며, true 인 경우 기존 속성이
대체됩니다.
글로벌 속성 설정 (초기화 후)
"Set Global Properties" 태그 유형을 사용하여 런타임에 Singular 속성을 추가하거나 업데이트합니다.
Track Type: setGlobalProperties
propertyKey: user_type
value: premium
글로벌 속성 가져오기
"글로벌 속성 가져오기" 태그 유형을 사용하여 현재 글로벌 속성 객체를 읽습니다. 글로벌 속성 객체를 저장하기 위해 데이터 레이어 키 이름을 설정할 수 있습니다.
Track Type: getGlobalProperties
글로벌 속성 해제
"글로벌 속성 해제" 태그 유형을 사용하여 전체 객체를 지우지 않고 Singular 속성 키를 제거합니다.
Track Type: unsetGlobalProperty
propertyKey: user_type
글로벌 속성 전체 지우기
"글로벌 속성 전체 삭제" 태그 유형을 사용하여 모든 글로벌 속성을 제거합니다.
Track Type: clearGlobalProperties
자연 검색 추적
자연 검색 추적 설정 태그 생성
중요! - 이 태그는 Singular SDK 초기화 전에 반드시 실행되어야 합니다!
이 커스텀 HTML 태그는 문서 URL을 수정하여 Singular 웹 SDK가 초기화 중에 읽어야 하는 자연 검색 추적 매개변수(wpsrc 및 wpcn)를 추가합니다. 태그 순서는 올바른 실행 순서를 보장하기 위해 매우 중요합니다.
이 예시는 워크어라운드 솔루션으로 제공되어 유기적 검색 추적을 활성화합니다. 코드는 예시 용도로만 사용해야 하며, 마케팅 부서의 요구에 따라 웹 개발자가 업데이트 및 유지 관리해야 합니다. 유기적 검색 추적은 광고주마다 다른 의미를 가질 수 있습니다. 샘플을 검토하고 필요에 맞게 조정하십시오.
사용 이유
-
캠페인 매개변수가 없더라도 자연 검색 방문이 제대로 추적되도록 보장합니다.
-
명확한 기여도 측정을 위해 URL에 (리퍼러)의 값을 가진 Singular형 "Source" 매개변수
wpsrc및 "Campaign Name" 매개변수wpcn을 "OrganicSearch"로 추가합니다. -
나중에 사용할 수 있도록 현재 URL과 리퍼러를
localStorage에 저장합니다. -
순수 자바Script, 제로 의존성, 쉬운 연동.
작동 방식
-
페이지 URL에서 알려진 캠페인 매개변수(Google, Facebook, TikTok, UTM 등)를 확인합니다.
-
캠페인 매개변수가 없고 리퍼러가 검색 엔진인 경우 다음을 추가합니다:
-
wpsrc(리퍼러를 값으로 함) -
wpcn(값으로 'OrganicSearch' 사용)
-
-
페이지를 재로드하지 않고 브라우저의 URL을 업데이트합니다.
-
현재 URL과 리퍼러를
localStorage에sng_url및sng_ref으로 저장합니다.
사용법
- GTM에서 태그 > 새로 만들기로 이동하여 태그 구성을 클릭한 후 사용자 정의 HTML을 선택합니다.
- 아래와 같이 전체 JavaScript 코드를 붙여넣습니다.
-
이 태그에 대한 트리거 생성은 생략합니다. 이 태그는 Singular 초기화 태그보다 먼저 실행되어야 하므로, 태그 시퀀싱을 사용하여 초기화 태그보다 먼저 발동되도록 구성합니다.
- "Singular - Organic Search Setup"과 같이 설명적인 이름을 사용하세요.
- Singular 웹 SDK 초기화 태그를 엽니다.
- 태그 구성을 클릭하세요.
- 고급 설정 > 태그 시퀀싱으로 이동합니다.
- "[Singular 초기화 태그] 실행 전에 설정 태그 실행"을 선택하세요.
- 드롭다운에서 "Singular - Organic Search Setup" 태그를 선택하세요. 권장: [설정 태그]가 실패할 경우 [Singular Init Tag]를 실행하지 않도록 "[설정 태그]가 실패할 경우 [Singular Init Tag] 실행 안 함"을 선택하세요.
- 권장: URL 수정이 불완전한 상태에서 초기화가 이루어지지 않도록 [설정 태그] 실패 시 [Singular 초기화 태그]를 발동하지 않도록 체크하세요.
- 태그 저장.
-
GTM의 미리보기 모드로 확인하세요:
- 설정 태그가 먼저 실행되어 URL을 수정합니다.
- Singular 초기화 태그가 두 번째로 실행되어 수정된 URL 매개변수를 읽습니다.
- 태그 간 타이밍 충돌이 발생하지 않습니다.
고급 태그 시퀀싱의 경우: Google의 공식 문서를 참조하세요:
<script>
(function() {
// singular-web-organic-search-tracking: setupOrganicSearchTracking.js
// Tracks organic search referrals by appending wpsrc and wpcn to the URL if no campaign parameters exist and the referrer is a search engine.
// Configuration for debugging (set to true to enable logs)
var debug = true;
// List of campaign parameters to check for exclusion
var campaignParams = [
'gclid', 'fbclid', 'ttclid', 'msclkid', 'twclid', 'li_fat_id',
'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'wpsrc'
];
// Whitelist of legitimate search engine domains (prevents false positives)
var legitimateSearchEngines = new Set([
// Google domains
'google.com', 'google.co.uk', 'google.ca', 'google.com.au', 'google.de',
'google.fr', 'google.it', 'google.es', 'google.co.jp', 'google.co.kr',
'google.com.br', 'google.com.mx', 'google.co.in', 'google.ru', 'google.com.sg',
// Bing domains
'bing.com', 'bing.co.uk', 'bing.ca', 'bing.com.au', 'bing.de',
// Yahoo domains
'yahoo.com', 'yahoo.co.uk', 'yahoo.ca', 'yahoo.com.au', 'yahoo.de',
'yahoo.fr', 'yahoo.it', 'yahoo.es', 'yahoo.co.jp',
// Other search engines
'baidu.com', 'duckduckgo.com', 'yandex.com', 'yandex.ru',
'ask.com', 'aol.com', 'ecosia.org', 'startpage.com',
'qwant.com', 'seznam.cz', 'naver.com', 'daum.net'
]);
// Extract main domain from hostname (removes subdomains)
function getMainDomain(hostname) {
if (!hostname) return '';
var lowerHost = hostname.toLowerCase();
// Handle special cases for known search engines with country codes
var searchEnginePatterns = {
'google': function(host) {
// Match google.TLD patterns more precisely
if (host.indexOf('google.co.') !== -1 || host.indexOf('google.com') !== -1) {
var parts = host.split('.');
for (var i = 0; i < parts.length - 1; i++) {
if (parts[i] === 'google') {
return parts.slice(i).join('.');
}
}
}
return null;
},
'bing': function(host) {
if (host.indexOf('bing.co') !== -1 || host.indexOf('bing.com') !== -1) {
var parts = host.split('.');
for (var i = 0; i < parts.length - 1; i++) {
if (parts[i] === 'bing') {
return parts.slice(i).join('.');
}
}
}
return null;
},
'yahoo': function(host) {
if (host.indexOf('yahoo.co') !== -1 || host.indexOf('yahoo.com') !== -1) {
var parts = host.split('.');
for (var i = 0; i < parts.length - 1; i++) {
if (parts[i] === 'yahoo') {
return parts.slice(i).join('.');
}
}
}
return null;
}
};
// Try specific patterns for major search engines
for (var engine in searchEnginePatterns) {
if (lowerHost.indexOf(engine) !== -1) {
var result = searchEnginePatterns[engine](lowerHost);
if (result) return result;
}
}
// Handle other known engines with simple mapping
var otherEngines = {
'baidu.com': 'baidu.com',
'duckduckgo.com': 'duckduckgo.com',
'yandex.ru': 'yandex.ru',
'yandex.com': 'yandex.com',
'ask.com': 'ask.com',
'aol.com': 'aol.com',
'ecosia.org': 'ecosia.org',
'startpage.com': 'startpage.com',
'qwant.com': 'qwant.com',
'seznam.cz': 'seznam.cz',
'naver.com': 'naver.com',
'daum.net': 'daum.net'
};
for (var domain in otherEngines) {
if (lowerHost.indexOf(domain) !== -1) {
return otherEngines[domain];
}
}
// Fallback: Extract main domain by taking last 2 parts (for unknown domains)
var parts = hostname.split('.');
if (parts.length >= 2) {
return parts[parts.length - 2] + '.' + parts[parts.length - 1];
}
return hostname;
}
// Get query parameter by name, using URL.searchParams with regex fallback for IE11
function getParameterByName(name, url) {
if (!url) url = window.location.href;
try {
return new URL(url).searchParams.get(name) || null;
} catch (e) {
if (debug) console.warn('URL API not supported, falling back to regex:', e);
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
var results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
}
// Check if any campaign parameters exist in the URL
function hasAnyParameter(url, params) {
for (var i = 0; i < params.length; i++) {
if (getParameterByName(params[i], url) !== null) {
return true;
}
}
return false;
}
// Improved search engine detection - only checks hostname, uses whitelist
function isSearchEngineReferrer(referrer) {
if (!referrer) return false;
var hostname = '';
try {
hostname = new URL(referrer).hostname.toLowerCase();
} catch (e) {
// Fallback regex for hostname extraction (IE11 compatibility)
var match = referrer.match(/^(?:https?:\/\/)?([^\/\?#]+)/i);
hostname = match ? match[1].toLowerCase() : '';
}
if (!hostname) return false;
// First check: exact match against whitelist
if (legitimateSearchEngines.has(hostname)) {
if (debug) console.log('Exact match found for:', hostname);
return true;
}
// Second check: subdomain of legitimate search engine
var hostParts = hostname.split('.');
if (hostParts.length >= 3) {
// Try domain.tld combination (e.g., google.com from www.google.com)
var mainDomain = hostParts[hostParts.length - 2] + '.' + hostParts[hostParts.length - 1];
if (legitimateSearchEngines.has(mainDomain)) {
if (debug) console.log('Subdomain match found for:', hostname, '-> main domain:', mainDomain);
return true;
}
// Try last 3 parts for country codes (e.g., google.co.uk from www.google.co.uk)
if (hostParts.length >= 3) {
var ccDomain = hostParts[hostParts.length - 3] + '.' + hostParts[hostParts.length - 2] + '.' + hostParts[hostParts.length - 1];
if (legitimateSearchEngines.has(ccDomain)) {
if (debug) console.log('Country code domain match found for:', hostname, '-> cc domain:', ccDomain);
return true;
}
}
}
if (debug) {
console.log('Hostname not recognized as legitimate search engine:', hostname);
}
return false;
}
// Main function to update URL with organic search tracking parameters
function setupOrganicSearchTracking() {
var url = window.location.href;
var referrer = document.referrer || '';
// Store URL and referrer in localStorage
try {
localStorage.setItem('sng_url', url);
localStorage.setItem('sng_ref', referrer);
} catch (e) {
if (debug) console.warn('localStorage not available:', e);
}
if (debug) {
console.log('Current URL:', url);
console.log('Referrer:', referrer);
}
// Skip if campaign parameters exist or referrer is not a search engine
var hasCampaignParams = hasAnyParameter(url, campaignParams);
if (hasCampaignParams || !isSearchEngineReferrer(referrer)) {
if (debug) console.log('Skipping URL update: Campaign params exist or referrer is not a legitimate search engine');
return;
}
// Extract and validate referrer hostname
var referrerHostname = '';
try {
referrerHostname = new URL(referrer).hostname;
} catch (e) {
if (debug) console.warn('Invalid referrer URL, falling back to regex:', e);
var match = referrer.match(/^(?:https?:\/\/)?([^\/]+)/i);
referrerHostname = match ? match[1] : '';
}
// Extract main domain from hostname
var mainDomain = getMainDomain(referrerHostname);
if (debug) {
console.log('Full hostname:', referrerHostname);
console.log('Main domain:', mainDomain);
}
// Only proceed if main domain is valid and contains safe characters
if (!mainDomain || !/^[a-zA-Z0-9.-]+$/.test(mainDomain)) {
if (debug) console.log('Skipping URL update: Invalid or unsafe main domain');
return;
}
// Update URL with wpsrc and wpcn parameters
var urlObj;
try {
urlObj = new URL(url);
} catch (e) {
if (debug) console.warn('URL API not supported, cannot modify URL:', e);
return;
}
// Set wpsrc to the main domain (e.g., google.com instead of tagassistant.google.com)
urlObj.searchParams.set('wpsrc', mainDomain);
// Set wpcn to 'Organic Search' to identify the campaign type
urlObj.searchParams.set('wpcn', 'Organic Search');
// Update the URL without reloading (check if history API is available)
if (window.history && window.history.replaceState) {
try {
window.history.replaceState({}, '', urlObj.toString());
if (debug) console.log('Updated URL with organic search tracking:', urlObj.toString());
} catch (e) {
if (debug) console.warn('Failed to update URL:', e);
}
} else {
if (debug) console.warn('History API not supported, cannot update URL');
}
}
// Execute the function
setupOrganicSearchTracking();
})();
</script>
크로스 서브도메인 추적
기본적으로 Singular 웹사이트 SDK는 Singular 기기 ID를 생성하고 브라우저 스토리지를 사용하여 이를 유지합니다. 이 스토리지는 서브도메인 간에 공유될 수 없으므로, SDK는 각 서브도메인마다 새 ID를 생성하게 됩니다.
서브도메인 간에 Singular 기기 ID를 지속 유지하려면 다음 옵션 중 하나를 사용할 수 있습니다: 방법 A: 쿠키를 사용한 자동 지속 유지
방법 B (고급): Singular 기기 ID 수동 설정
Singular SDK가 기기 ID를 자동으로 지속하지 않도록 하려면, 도메인 간에 ID를 수동으로 지속할 수 있습니다. 예를 들어 최상위 도메인 쿠키나 서버 측 쿠키를 사용하세요. 값은 Singular에서 생성한 유효한 uuid4 형식의 ID여야 합니다.
참고: Singular Device ID는 사용자 정의 JavaScript 변수를 정의하고 Init 추적 유형 태그 호출 후 singularSdk.getSingularDeviceId()를 호출하여 읽을 수 있습니다.
일반적인 GTM 구현 문제점
| 필수 기기 식별자 | |
|---|---|
| 이벤트가 여러 번 발생함 | 트리거를 세분화하거나 제한하고, "페이지당 한 번"을 사용하거나 조건을 추가하세요 |
| 잘못된 제품 ID 형식 |
제품 ID는 역 DNS 표기법(com.company.site)을 사용해야 함
|
| 이벤트가 추적되지 않음 |
이벤트 이름의 철자와 대소문자를 확인하십시오. 이벤트 태그가 발생하기 전에 singular
SDK가 로드되었는지 확인하십시오
|
| SDK Script 차단됨 | 광고 차단기 또는 제한적인 콘텐츠 보안 정책; 문제가 지속될 경우 네이티브 JS 구현으로 전환을 고려하십시오 |
모범 사례
- GTM 체계 유지: 태그와 트리거를 명확하게 명명하고 목적을 문서화하십시오.
- 사용되지 않거나 구식 태그를 정기적으로 점검하십시오.
- 중복 이벤트 발생 위험을 줄이기 위해 트리거 수를 최소화하십시오.
- 변경 후에는 항상 GTM의 미리보기 모드에서 철저히 테스트한 후 실제 적용하십시오.
- 쿠키 기반 추적(크로스 서브도메인 추적)을 사용하는 경우 개인정보 처리방침을 해당 내용에 맞게 업데이트하십시오.