Skip to main content
이벤트를 사용하면 장바구니에서 무언가가 일어났을 때 코드를 실행할 수 있어요. window.aftersell.cart.events 아래에 있어요. 구독은 설정용 호출이므로 스크립트 맨 위에서 해도 안전하며, ready()를 기다릴 필요가 없어요.

사용 가능한 이벤트

구독하기

events.on(event, handler)는 핸들러를 등록하고 구독을 해제하는 함수를 반환해요:
  • events.once(event, handler): 한 번 실행된 후 스스로 구독을 해제해요.
  • events.off(event, handler): 특정 핸들러를 제거해요.
예외를 던지는 핸들러는 격리되어 콘솔에 기록되며, 다른 핸들러는 계속 실행돼요.

두 가지 규칙

거의 모든 이벤트 버그는 이 둘 중 하나로 귀결돼요.

가드 없이 cart_updated에서 장바구니를 변경하지 마세요

cart_updated 핸들러 안에서 장바구니를 변경하면 cart_updated가 다시 발생해요. 그 핸들러가 장바구니를 또 변경하면 무한 루프가 생겨요. 페이지가 Shopify를 두들기는 동안 쇼핑객은 장바구니가 요동치는 것을 보게 돼요.
cart_updatedcart_loaded에서 액션을 무조건 호출하지 마세요. 만들려는 상태를 검사하는 가드를 두어, 두 번째 실행에서는 아무것도 하지 않도록 하세요.
장바구니에는 안전망이 하나 있어요: 동일한 장바구니를 만드는 업데이트는 아무것도 발생시키지 않으므로, 아무것도 변경하지 않는 다시 가져오기는 사이클을 재시작하지 않아요. 이는 의도치 않은 no-op 루프로부터 보호해 줘요. 하지만 매번 실제로 장바구니를 변경하는 핸들러로부터는 보호해 주지 않아요.

페이로드는 읽기 전용으로 다루세요

하나의 이벤트에 대한 모든 핸들러는 같은 객체를 받아요. 이를 변경하면 이후 핸들러가 보는 내용이 바뀌며, 스토어의 다른 앱에 속한 핸들러도 영향을 받아요.
실제로 장바구니를 변경하려면 액션을 사용하세요. 라인 렌더링 방식을 변경하려면 registerLineTransform을 사용하세요.

cart_loaded

장바구니가 페이지에서 처음 로드될 때 한 번 발생해요. 페이로드는 전체 cart 객체예요.
용도: 무료 선물 조정, 위젯 초기화, 페이지 로드 시 장바구니 콘텐츠의 분석 보고처럼 장바구니의 시작 상태를 기준으로 실행해야 하는 모든 작업이에요. cart_loaded는 늦은 구독자에게 재생돼요. 장바구니가 이미 로드된 후 구독하면 핸들러가 현재 장바구니와 함께 즉시 호출돼요. 구독 순서는 전혀 중요하지 않으므로, 스크립트가 장바구니보다 먼저 실행됐는지 걱정할 필요가 없어요.
페이지 로드 시와 이후 모든 변경 시 모두 올바르게 동작해야 하는 로직은 같은 함수로 cart_loadedcart_updated 모두에 구독해야 해요. 이것이 “X를 장바구니와 동기화 유지”의 표준 패턴이에요.

cart_updated

첫 로드 이후 장바구니 콘텐츠가 변경될 때마다 발생해요. 드로어에서든, 여러분의 액션에서든, 테마에서든, 다른 앱에서든 마찬가지예요. 페이로드는 전체 cart 객체예요.
용도: 커스텀 합계, 진행률 바, 헤더 배지, 변경 시마다의 분석 이벤트처럼 장바구니 외부의 무언가를 동기화하는 데 사용하세요. 동일한 장바구니를 만드는 업데이트는 아무것도 발생시키지 않아요. 드로어를 다시 열거나, 탭을 다시 전환하거나, 같은 콘텐츠를 반환하는 다시 가져오기는 이벤트를 발생시키지 않아요.
여기서 액션을 호출하기 전에 두 가지 규칙을 다시 읽어 보세요.

item_added

장바구니에 새 라인이 나타날 때 발생해요. 페이로드는 { item }이며, item장바구니 라인이에요.
용도: 서드파티 분석 도구에서의 장바구니 담기 추적이에요. 이것이 SDK의 가장 흔한 사용 사례예요. 장바구니 담기 추적하기를 참고하세요. 이벤트 도출 방식에 대해 알아야 할 두 가지가 있어요:
수량 변경은 추가가 아니에요. 장바구니는 수량이 아니라 라인의 차이를 비교해 추가와 제거를 판단해요. 쇼핑객이 라인을 1에서 3으로 올리면 item_added가 아니라 cart_updated가 발생해요. 수량 증가도 포착해야 한다면 cart_updated 핸들러에서 이전 상태와 비교하세요.
또한 페이지가 로드될 때 이미 장바구니에 있던 상품에는 발생하지 않아요. 그런 상품은 cart_loaded를 통해 도착해요. 서로 다른 상품 여러 개를 한 번에 추가하면 라인당 한 번씩 이벤트가 발생해요.

item_removed

장바구니에서 라인이 사라질 때 발생해요. 페이로드는 { item }으로, 사라지기 직전의 라인이므로 key, variantId, title을 여전히 읽을 수 있어요.
용도: 플래그 지우기, 쇼핑객이 거절한 오퍼 다시 표시하기, 제거 사항을 분석에 보고하기처럼 추가 시 했던 작업을 되돌리는 데 사용하세요. item_added와 같은 주의 사항이 있어요: 0에 도달하지 않는 수량 감소는 제거가 아니에요.

cart_opened와 cart_closed

드로어가 열리고 닫힐 때 발생해요. 페이로드는 없어요.
용도: 조회 추적, 드로어 뒤의 동영상이나 캐러셀 일시 정지, 페이지의 클래스 토글이에요. 둘 다 초기 페이지 로드에는 발생하지 않으며, 실제로 열리거나 닫힐 때만 발생해요.

checkout

쇼핑객이 결제 버튼을 클릭할 때, 브라우저가 이동하기 직전에 발생해요. 페이로드는 없어요.
용도: 결제 의도 추적이에요.
이 핸들러에서 결제를 취소할 수 없어요. 이 이벤트는 게이트가 아니라 알림이며, 코드가 무엇을 하든 페이지 이동은 일어나요. 핸들러는 빠르고 동기적으로 유지하세요: await나 느린 네트워크 호출은 페이지가 언로드되기 전에 끝나지 않을 수 있어요. 반드시 전송해야 하는 것은 navigator.sendBeacon을 사용하세요.

SDK 외부에서 수신하기

모든 이벤트는 window에서 DOM CustomEvent로도 디스패치되므로, window.aftersell.cart를 건드리지 않고도 수신할 수 있어요. 테마 파일, 서드파티 앱, 장바구니와 독립적으로 로드되는 스크립트에서 유용해요. 이름에 주의하세요: 버스는 snake_case를, DOM 이벤트는 aftersell:cart: 접두사 뒤에 kebab-case를 사용해요.
페이로드는 event.detail에 담기며 cart 객체와 일치해요. 이벤트는 window에서 디스패치되므로 페이지 어디에 있는 리스너든 받을 수 있어요. 장바구니는 shadow root에서 렌더링되지만, shadow 경계는 이벤트 경로에 절대 포함되지 않아요. 디스패치마다 페이로드가 복제되므로, event.detail을 변경하는 리스너가 다른 리스너에 영향을 줄 수 없고, 예외를 던지는 리스너도 SDK를 방해할 수 없어요.
cart-loaded는 DOM에서 재생되지 않아요. 버스는 cart_loaded를 늦은 구독자에게 재생하지만, 그 경로는 DOM 디스패치를 우회하므로 장바구니가 이미 로드된 후에 등록한 window.addEventListener('aftersell:cart:cart-loaded')는 절대 발생하지 않아요. 스크립트의 로드 순서가 보장되지 않으면, 재생이 되는 window.aftersell.cart.events.on('cart_loaded', …)를 사용하거나 aftersell:cart:cart-updated도 함께 수신하세요.

Shopify 표준 장바구니 이벤트

별도로, 장바구니는 장바구니를 변경할 때마다 document에서 Shopify의 표준 장바구니 이벤트를 발행하므로, 테마 코드와 다른 앱이 테마의 변경에 반응하는 것과 같은 방식으로 Aftersell의 변경에 반응할 수 있어요:
페이로드는 event.detail에 없어요. detail에는 { source: 'aftersell' }만 담겨 있어요 — 장바구니가 루프를 도는 대신 자체 이벤트를 무시하는 데 사용하는 태그예요. 위 표의 모든 항목은 이벤트 객체에 직접 할당되므로 event.detail.action이 아니라 event.action을 읽으세요.
각 이벤트에는 기반 쓰기 작업이 완료될 때 Aftersell이 settle하는 promise도 담겨 있어요. Shopify 표준과 일치해요 — await하고, 직접 resolve하지 마세요. 이 이벤트들은 document에서 디스패치되고 버블링되므로 window 리스너도 받을 수 있어요.

다음 단계

  • Cart 객체: 위 페이로드의 전체 구조예요.
  • 액션: 핸들러에서 장바구니를 변경하는 방법이에요.
  • : 장바구니에 반응하는 대신 렌더링 방식을 변경하는 데 사용해요.
  • 사용 사례: 분석 추적, 무료 선물 등 완전한 예제예요.