> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/event-management/properties/utm.md).

# 캠페인 속성 (UTM)

## UTM 캠페인 정보 관리 방식

Hackle Web SDK는 사용자가 어떤 마케팅 캠페인을 통해 유입되었는지 자동으로 수집·저장하고, 이후 발생하는 이벤트에 유입 정보를 연결합니다. 이 문서는 UTM 파라미터가 **언제 저장되고, 언제 유지되며, 언제 초기화되는지**를 설명합니다.

### 사용 가능한 SDK 버전

| SDK              | 버전       |
| ---------------- | -------- |
| `javascript-sdk` | 11.18.0+ |
| `react-sdk`      | 11.18.0+ |

### 수집되는 파라미터

SDK는 페이지 URL의 쿼리 스트링에서 아래 파라미터를 자동으로 읽어들입니다.

| 구분       | 파라미터                                                                            |
| -------- | ------------------------------------------------------------------------------- |
| UTM      | `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`, `utm_id` |
| 광고 클릭 ID | `gclid` (Google Ads), `fbclid` (Meta/Facebook)                                  |

* 값이 **빈 문자열인 파라미터는 무시**됩니다. (예: `?utm_source=` 는 수집되지 않음)
* 수집된 값은 **사용자 프로퍼티로 저장**되며, 새로운 캠페인이 감지될 때 유입 이벤트가 함께 발생합니다.
* 어트리뷰션 모델은 **라스트 터치(Last-touch)** 입니다. 새로운 UTM으로 다시 유입되면 이전 값을 덮어씁니다.

### 저장 방식

수집된 UTM 정보는 **퍼스트파티 쿠키**에 저장됩니다.

| 항목     | 내용                                             |
| ------ | ---------------------------------------------- |
| 저장 위치  | 브라우저 쿠키                                        |
| 도메인 범위 | 루트 도메인 기준 (예: `.example.com` — **서브도메인 간 공유**) |

{% hint style="info" %}
쿠키에 저장되므로 페이지 새로고침, 리다이렉트, 새 탭, 서브도메인 이동에도 **저장된 값 자체는 사라지지 않습니다.** 값이 바뀌는 것은 SDK가 아래의 "재평가" 과정을 통해 명시적으로 갱신하거나 초기화할 때뿐입니다.
{% endhint %}

### UTM 정보가 갱신되는 시점 (재평가)

SDK는 아래 두 시점에만 현재 URL을 다시 확인하여 UTM 정보를 갱신할지 판단합니다.

1. **페이지가 새로 로드될 때** — 최초 진입, 새로고침, 서버 왕복이 있는 페이지 전환 등 SDK가 다시 초기화되는 모든 경우.
2. **새로운 세션이 시작될 때** — 아래 조건 중 하나:
   * 사용자 식별자(userId)가 변경됨 (예: 로그인/로그아웃)
   * 세션 타임아웃(기본 **30분**의 비활동) 이후 새 이벤트가 발생함

{% hint style="info" %}
새로고침이 없는 SPA(Single Page Application)의 클라이언트 사이드 라우팅만으로는 이 재평가가 발생하지 않습니다. 즉, 한 세션 동안 페이지를 이동해도 SDK가 다시 로드되거나 새 세션이 시작되지 않으면 **UTM 정보는 처음 진입 시점의 값으로 고정**됩니다.
{% endhint %}

### 유지 · 갱신 · 초기화 판정 규칙

재평가가 실행되면, SDK는 **현재 페이지 URL의 UTM 값**과 **직전 페이지(리퍼러)** 를 함께 보고 다음과 같이 판단합니다.

| 현재 URL 상태              | 유입 경로                                       | 동작                                |
| ---------------------- | ------------------------------------------- | --------------------------------- |
| UTM **있음**, 이전 저장값과 다름 | 무관                                          | **갱신** (새 캠페인으로 덮어쓰기 + 유입 이벤트 발생) |
| UTM **있음**, 이전 저장값과 동일 | 무관                                          | **유지** (변화 없음, 중복 이벤트 없음)         |
| UTM **없음**             | **같은 도메인 내 이동** (직전 페이지가 우리 사이트)            | **유지**                            |
| UTM **없음**             | **외부 사이트에서 유입** 또는 **리퍼러 없음**(주소 직접 입력·북마크) | **초기화** (저장돼 있던 UTM 삭제)           |

핵심 요약:

* **유지되는 경우는 두 가지뿐입니다.** ① UTM 없이 같은 도메인 안에서 이동했을 때, ② 현재 URL의 UTM이 기존 저장값과 완전히 동일할 때.
* 그 외 재평가 시점에 **"UTM 없음 + 외부/직접 유입"** 이 감지되면 기존 UTM은 **초기화**됩니다.
* 판정의 기준축은 **리퍼러(직전 페이지)의 도메인**입니다.

### 상황별 동작

| 상황                                     | 결과     | 설명                                |
| -------------------------------------- | ------ | --------------------------------- |
| **UTM 링크로 최초 유입**                      | 저장     | 캠페인 정보 저장 + 유입 이벤트 발생             |
| **같은 UTM URL 새로고침**                    | 유지     | 값이 동일하므로 변화·중복 이벤트 없음             |
| **새로운 UTM 링크로 재유입**                    | 갱신     | 마지막 유입 캠페인으로 덮어쓰기 (Last-touch)    |
| **사이트 내부 링크로 페이지 전환** (같은 도메인, UTM 없음) | 유지     | 리퍼러가 자사 도메인 → 기존 UTM 유지           |
| **SPA 라우팅** (새로고침 없는 페이지 이동)           | 유지(고정) | 재평가 미발생. 진입 시점의 UTM이 세션 내내 유지됨    |
| **주소 직접 입력 / 북마크 재방문** (UTM 없음)        | 초기화    | 리퍼러가 없어 "외부/직접 유입"으로 판정 → 저장값 삭제  |
| **외부 OAuth 로그인 후 복귀** (콜백 URL에 UTM 없음) | 초기화 위험 | 복귀 페이지의 리퍼러가 외부(인증 제공자) 도메인 → 초기화 |
| **외부 결제(PG) 후 복귀** (콜백 URL에 UTM 없음)    | 초기화 위험 | 위와 동일. 리퍼러가 결제사 도메인일 경우 초기화       |

#### SPA 환경 참고

새로고침 없이 라우팅하는 SPA에서는 최초 진입 시 잡힌 UTM이 세션 동안 유지되어 안정적입니다. 다만 반대로, **최초 진입 이후 라우팅 과정에서만 나타난 UTM 파라미터는 즉시 수집되지 않을 수 있습니다.** 해당 값이 수집되려면 다음 페이지 로드나 새 세션이 시작되는 시점에 URL에 그 UTM이 남아 있어야 합니다.

#### 외부 리다이렉트(OAuth · 결제) 주의

외부 인증/결제 페이지로 이동했다가 복귀하면, 복귀 페이지는 **풀 페이지 로드**로 처리되어 재평가가 발생합니다. 이때 복귀 URL(콜백 URL)에 UTM이 없고 리퍼러가 외부 도메인(인증 제공자·결제사)이면, 규칙상 **저장돼 있던 UTM이 초기화**됩니다. 로그인 과정에서 사용자 식별자가 바뀌면 새 세션까지 함께 시작되어 동일한 결과로 이어집니다.

### 권장사항

* **외부 리다이렉트 후에도 UTM을 유지하려면**, 복귀(콜백) URL에 원래의 UTM 파라미터를 그대로 실어 되돌아오도록 리다이렉트를 구성하세요. 콜백 URL에 UTM이 포함되어 있으면, 재평가 시 동일 값으로 유지되거나 그대로 재적용됩니다.
* 캠페인 성과를 정확히 측정하려면 **유입 링크(광고·메일 등)에 UTM 파라미터를 일관되게 부착**하세요.
* SPA에서 유입 직후 특정 이벤트를 캠페인과 함께 남기고 싶다면, 진입 시점 URL에 UTM이 포함되어 있는지 확인하세요.

#### 결제·로그인 등 외부 페이지를 다녀온 뒤에도 UTM 이어가기

**상황.** 외부 결제(PG)나 소셜 로그인(OAuth)을 거치면, 돌아온 페이지의 주소(URL)에는 보통 UTM이 없고 "직전 페이지"가 외부 사이트(결제사·로그인 제공자)로 기록됩니다. 그러면 SDK는 이를 "새로운·직접 유입"으로 판단해 **그동안 저장해 둔 UTM을 초기화**할 수 있습니다.

**해결 원리 (한 문장).** 외부에 다녀와서 **돌아오는 주소(콜백 URL)에 원래의 UTM을 다시 붙여주면**, SDK가 같은 캠페인으로 인식해 UTM을 그대로 이어갑니다. → SDK 수정 없이, 사이트(고객사) 쪽 설정만으로 해결할 수 있습니다.

{% hint style="info" icon="lightbulb-on" %}
결제/로그인이 끝나고 **돌아오는 링크 주소에 UTM을 그대로 달아 달라**고 개발팀에 요청하면 됩니다.
{% endhint %}

**방법 비교**

| 방법                            | 난이도 | 권장도 | 설명                                         |
| ----------------------------- | --- | --- | ------------------------------------------ |
| 복귀 URL(returnUrl)에 UTM 다시 붙이기 | 낮음  | ★★★ | 결제·로그인 종류와 무관하게 동작하는 가장 확실한 방법             |
| 팝업/창(iframe)으로 결제 진행          | 중간  | ★★☆ | 원래 페이지를 벗어나지 않아 UTM이 그대로 유지됨 (모바일에선 제약 가능) |
| 자사 도메인 콜백을 거쳐 복귀              | 중간  | ★☆☆ | 단독으로는 불안정 → 위 "URL에 UTM 붙이기"와 함께 쓰는 것을 권장  |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/event-management/properties/utm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
