[GA4>M 활용] GTM 데이터레이어(dataLayer) 구조 완전정복 : 중첩 키·배열에서 값 가져오는 방법 (튜토리얼 2편)
핵심 요약
dataLayer의 중첩된 값은 점 표기법(dot notation) 으로 가져옵니다. 예를 들어 attributes 안의 pagePostAuthor는 attributes.pagePostAuthor 로, 전자상거래 items 배열의 첫 번째 상품 가격은 ecommerce.items.0.price 로 지정합니다. GTM은 대괄호([0])를 지원하지 않아 인덱스도 점으로 씁니다.
이 글에서 알 수 있는 것
- dataLayer 데이터 구조의 여러 형태(루트/중첩/배열)
- push가 기존 객체를 덮어쓰는 동작과 '깨끗한 dataLayer'의 의미
- 중첩 키(하위 키)에서 값 가져오기 — 점 표기법
- 전자상거래 items 배열에서 특정 상품 값 가져오기 (undefined 오류 해결)
- GTM이 대괄호 대신 점 표기법을 쓰는 이유
✳️ 난이도 : 중급~고급 | 소요 시간 : 약 10분 | 주의 : 개발 용어가 많이 나옵니다. 전체 맥락 이해를 목표로 하고, 실제 구현은 개발자와 함께 보는 것을 권장합니다.
이전 글 : GTM 데이터레이어 튜토리얼 1편 — dataLayer 개념, 데이터 영역 변수 기본
dataLayer 데이터 구조에는 어떤 형태가 있나요?
dataLayer에 값을 담는 구조는 크게 3가지 형태로 나뉩니다: ① 루트 수준, ② 중첩(자손) 키, ③ 배열입니다. 값을 어떻게 담느냐에 따라 GTM에서 값을 꺼내는 방법(변수 이름)이 달라집니다.
| 구조 | 예시 | GTM 변수 이름 |
| ① 루트 수준 | { pagePostAuthor: '홍길동' } | pagePostAuthor |
| ② 중첩(자손) 키 | { attributes: { pagePostAuthor: '홍길동' } } | attributes.pagePostAuthor |
| ③ 배열 | { ecommerce: { items: [ {price: 9.99}, ... ] } } | ecommerce.items.0.price |
push는 기존 데이터를 덮어쓴다 (반드시 알아야 할 동작)
dataLayer로 데이터를 push하면, 같은 키에 대해 전체 객체를 덮어씁니다. 이 동작을 모르면 데이터가 사라진 것처럼 보일 수 있습니다.
루트 수준 예시
가장 단순한 형태는 키가 루트 수준(객체의 최상위)에 있는 경우입니다.
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'pagePostAuthor': '홍길동'
});
</script>
이렇게 하면 pagePostAuthor가 루트 수준에 있어, GTM에서 변수 이름을 pagePostAuthor로 그대로 쓰면 값을 가져올 수 있습니다.
덮어쓰기 동작 확인하기
서로 다른 두 개의 push가 같은 authorData 키를 다룬다고 가정해 봅시다.
<script>
// 첫 번째 Push
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'authorData' : {
'pagePostAuthor': '홍길동'
}
});
// 두 번째 Push
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'authorData' : {
'pageCategory': 'GTM TIP',
'pagePostType': 'post'
}
});
</script>
최종 결과: dataLayer의 authorData에는 pageCategory와 pagePostType 두 값만 남습니다.
✳️ 이유 : 두 번째 push의 authorData가 첫 번째 push의 authorData를 완전히 덮어썼기 때문입니다. pagePostAuthor는 사라집니다.
✅ 결론 : 이런 덮어쓰기 방식은 이전 값 없이 "깨끗한" dataLayer를 원할 때 유용합니다. 반대로 값을 누적·병합하고 싶다면, 아래처럼 한 번의 push에 필요한 값을 모두 담아야 합니다.
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'authorData' : {
'pagePostAuthor': '홍길동',
'pageCategory': 'GTM TIP',
'pagePostType': 'post'
}
});
</script>
이렇게 하면 세 값이 모두 dataLayer에 남습니다.
중첩(자손) 키에서 값 가져오기 — 점 표기법
키가 다른 키 안에 중첩되어 있으면(하위 키), GTM 변수 이름에 점(.)으로 경로를 이어서 지정해야 합니다.
아래 예에서 attributes는 첫 번째 수준, pagePostAuthor는 두 번째 수준입니다. 즉 pagePostAuthor는 attributes 안에 중첩된 하위 키입니다.
{
attributes: {
pagePostAuthor: '홍길동'
}
}
이 값을 가져오려면 GTM 데이터 영역 변수 설정을 약간 바꿔야 합니다.

① 변수 이름에 pagePostAuthor 대신 attributes.pagePostAuthor 를 입력합니다.
더 깊게 중첩되어 있으면?
pagePostAuthor 안에 또 하위 키가 있다면 어떻게 될까요?
{
attributes: {
pagePostAuthor: {
authorName: '홍길동',
authorTag: 'Google Tag Manager'
}
}
}
이 경우 authorName에 대한 전체 경로는 attributes.pagePostAuthor.authorName 이 됩니다.
✅ 규칙 : 모든 레벨(단계)은 점(.)으로 구분합니다. 몇 단계가 중첩되든 경로를 점으로 이어서 최종 키를 만듭니다.
배열에서 값 가져오기 — 전자상거래 items (가장 실전적)
GA4 전자상거래 추적에서 가장 많이 쓰는 dataLayer는 주문 데이터를 push하는 부분입니다. 여기서 상품 정보는 '배열(items)'로 담기기 때문에, 특정 상품 값을 꺼내는 방법을 반드시 알아야 합니다.
아래는 구글 가이드라인 기준 purchase 이벤트의 dataLayer입니다.
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'T_12345',
affiliation: 'Google Merchandise Store',
value: 25.42,
tax: 4.90,
shipping: 5.99,
currency: 'USD',
coupon: 'SUMMER_SALE',
items: [
{
item_id: 'SKU_12345',
item_name: 'Stan and Friends Tee',
item_category: 'Apparel',
price: 9.99,
quantity: 1
},
{
item_id: 'SKU_12346',
item_name: 'Google Grey Women\'s Tee',
item_category: 'Apparel',
price: 20.99,
quantity: 1
}
]
}
});
흔한 실수: ecommerce.items.price → undefined
상품 가격을 가져오려고 변수 이름을 ecommerce.items.price로 설정하면 어떻게 될까요?


① 미리보기로 확인하면 undefined 메시지와 함께 값을 가져오지 못합니다.
왜 안 될까요?
ecommerce.items에는 상품이 2개 있어 item_name도 2개, price도 2개입니다. GTM은 어느 상품의 price를 가져와야 할지 알 수 없기 때문에 값을 반환하지 못합니다.
해결법: 인덱스를 점 표기법으로 지정
자바스크립트에서 첫 번째 상품 가격을 가져오려면 ecommerce.items[0].price를 씁니다. (인덱스는 0부터 시작)
✅ 핵심 : GTM은 대괄호([0])를 지원하지 않습니다. 따라서 대괄호 대신 점 표기법을 사용해, 최종 키를 ecommerce.items.0.price 로 지정해야 합니다.

① 데이터 영역 변수 이름을 ecommerce.items.0.price 로 설정합니다.
이제 미리보기로 테스트하면 첫 번째 상품 가격(9.99) 이 정상 수집됩니다.

인덱스 참고
| 가져올 값 | 변수 이름 |
| 첫 번째 상품 가격 | ecommerce.items.0.price |
| 두 번째 상품 가격 | ecommerce.items.1.price |
| 첫 번째 상품 이름 | ecommerce.items.0.item_name |
자주 묻는 질문 (FAQ)
Q. dataLayer는 GTM 스니펫 이전에 삽입되어야 하나요?
A. 네. Data Layer는 GTM 컨테이너 코드가 로드되기 전에 시작되어야 합니다. 즉, dataLayer.push가 웹사이트 <head> 영역의 GTM 컨테이너 스니펫보다 위에 있어야 합니다.
Q. GTM dataLayer는 어떻게 동작하나요?
A. dataLayer는 웹사이트에서 GTM 컨테이너로 정보를 전달하는 자바스크립트 객체입니다. GTM은 이 정보로 태그 구성의 변수를 채우고 트리거를 활성화합니다. dataLayer와 함께 배포될 때 가장 잘 작동합니다.
Q. push하면 왜 이전 값이 사라지나요?
A. 같은 키에 대해 뒤의 push가 앞의 값을 완전히 덮어쓰기 때문입니다. 값을 유지·병합하려면 한 번의 push에 필요한 값을 모두 담으세요.
Q. 중첩된 키 값은 어떻게 가져오나요?
A. 점 표기법을 씁니다. attributes 안의 pagePostAuthor는 attributes.pagePostAuthor, 그 안에 또 authorName이 있으면 attributes.pagePostAuthor.authorName 처럼 모든 단계를 점으로 잇습니다.
Q. ecommerce.items.price가 undefined로 나옵니다.
A. items가 배열이라 상품이 여러 개이기 때문입니다. GTM이 어느 상품인지 몰라 값을 못 가져옵니다. ecommerce.items.0.price 처럼 인덱스(0부터) 를 점 표기법으로 지정하세요.
Q. GTM에서 대괄호 [0]를 써도 되나요?
A. 안 됩니다. GTM은 이 컨텍스트에서 대괄호를 지원하지 않습니다. 자바스크립트의 items[0]은 GTM에서 items.0 으로 바꿔 써야 합니다.
요약 (한 장 정리)
- dataLayer 구조 3형태: 루트 / 중첩(자손) 키 / 배열
- push 동작: 같은 키는 덮어쓰기 → 유지하려면 한 번에 모아서 push
- 중첩 키: 점 표기법 → attributes.pagePostAuthor, attributes.pagePostAuthor.authorName
- 배열: 인덱스를 점으로 → ecommerce.items.0.price (0부터 시작)
- 핵심 함정: GTM은 대괄호 [0] 미지원 → items.0으로 표기
- 전자상거래: 주문 데이터 push가 실무에서 가장 많이 쓰는 dataLayer
작성 : 디애널리틱스(The Analytics) · 구글애널리틱스를 활용하여 기업의 마케팅 성과를 향상시키는 방법을 연구합니다.