Ideal House
콘텐츠로 이동

Shopify 개발자 연동#

Shopify 테마에 ideal.house 버튼을 추가하고 선택한 상품 옵션의 SKU에 매핑하세요.

<!-- DASHBOARD_READINESS -->

SDK를 불러오기 전에: Dashboard → Integration를 열고 **Allowed Origins (CORS)**에 스토어 출처를 추가한 다음 저장을 클릭하세요. 배포된 호스트 이름과 사용 중인 미리보기 또는 스테이징 출처를 포함하고, 여러 출처는 쉼표로 구분하세요. 설정 절차를 참고하세요.

신규 판매자는 검토가 필요한 15일 무료 체험을 신청할 수 있습니다. 승인되면 Dashboard에 로그인하여 상품을 업로드해 게시한 다음 여기로 돌아와 SDK를 설치하세요. 체험이 끝나도 공개 Marketplace 페이지는 유지되며 구독할 때까지 스토어 SDK가 일시 중지됩니다.

1. 사전 준비 확인#

  • 운영 테마 코드 또는 안전한 테마 복사본을 편집할 수 있어야 합니다.
  • 테스트 상품 하나 이상을 카탈로그로 가져왔으며 활성 상태여야 합니다.
  • 선택한 상품 옵션의 SKU는 카탈로그가 해당 스토어에 저장한 productCode와 같아야 합니다.

2. 버튼 스니펫 생성#

snippets/idealhouse-view-button.liquid#

liquid
{%- comment -%}
  Renders an ideal.house authored visualizer button.

  Accepts:
  - product_code: {String} Variant SKU used by the ideal.house Catalog mapping.
  - placement: {String} "card", "pdp-desktop", or "pdp-mobile".
{%- endcomment -%}

{%- liquid
  assign button_code = product_code | strip
  assign button_placement = placement | default: 'card'
-%}

<button
  type="button"
  class="idealhouse-view-button idealhouse-view-button--{{ button_placement | escape }}"
  data-idealhouse-authored-button
  data-active="false"
  {% if button_code != blank %}
    data-product-code="{{ button_code | escape }}"
  {% else %}
    disabled
  {% endif %}
  style="visibility: hidden;"
>
  <span>View in my room</span>
</button>

SDK가 상품의 사용 요건 충족을 확인할 때까지 버튼을 숨겨 두세요.

3. 테마 영역에 버튼 렌더링#

컬렉션 및 검색 카드#

liquid
{%- render 'idealhouse-view-button',
  product_code: card_product.selected_or_first_available_variant.sku,
  placement: 'card'
-%}

일반적으로 snippets/card-product.liquid, snippets/product-card.liquid 또는 snippets/product-grid-item.liquid 파일을 사용합니다. card_product를 테마에서 사용하는 상품 변수에 맞게 조정하세요.

상품 상세 페이지#

liquid
{%- render 'idealhouse-view-button',
  product_code: product.selected_or_first_available_variant.sku,
  placement: 'pdp-desktop'
-%}

{%- render 'idealhouse-view-button',
  product_code: product.selected_or_first_available_variant.sku,
  placement: 'pdp-mobile'
-%}

일반적으로 sections/main-product.liquid 또는 snippets/product.liquid 파일을 사용합니다. 테마에 별도 레이아웃이 있을 때만 데스크톱 및 모바일 렌더링을 각각 배치하세요.

4. SDK 불러오기 및 상품 옵션 동기화#

assets/idealhouse-room-visualizer.js#

js
(function () {
  'use strict';

  var buttonSelector = '[data-idealhouse-authored-button]';
  var sdkRequested = false;
  var buttonObserver = null;

  function resetButton(button) {
    button.dataset.active = 'false';
    button.style.visibility = 'hidden';
    delete button.dataset.rvProductCode;
    delete button.dataset.rvProductType;
    delete button.dataset.rvProductId;
    delete button.dataset.rvProductIds;
  }

  function syncButton(button, productCode) {
    if (!button) return false;
    var code = typeof productCode === 'string' ? productCode.trim() : '';
    resetButton(button);
    delete button.dataset.productCode;

    if (!code) {
      button.disabled = true;
      return false;
    }

    button.disabled = false;
    button.dataset.productCode = code;
    return true;
  }

  function syncButtons(container, productCode) {
    (container || document).querySelectorAll(buttonSelector).forEach(function (button) {
      syncButton(button, productCode);
    });
  }

  function loadSdk() {
    if (sdkRequested || !document.querySelector(buttonSelector)) return false;
    sdkRequested = true;
    if (buttonObserver) buttonObserver.disconnect();

    var script = document.createElement('script');
    script.src = 'https://sdk.ideal.house/sdk.js';
    script.async = true;
    script.dataset.shopId = '<SHOP_ID>';
    script.dataset.publishableKey = '<PUBLISHABLE_KEY>';
    script.dataset.authoredButtonSelector = buttonSelector;
    document.head.appendChild(script);
    return true;
  }

  function startSdkLoader() {
    if (loadSdk() || typeof MutationObserver === 'undefined') return;
    buttonObserver = new MutationObserver(loadSdk);
    buttonObserver.observe(document.documentElement, { childList: true, subtree: true });
  }

  // Dispatch this event from your theme's variant-change callback.
  document.addEventListener('idealhouse:variant-change', function (event) {
    var detail = event.detail || {};
    syncButtons(detail.container || document, event.detail && event.detail.sku);
  });

  window.IdealhouseShopify = {
    syncButton: syncButton,
    syncButtons: syncButtons
  };

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', startSdkLoader);
  } else {
    startSdkLoader();
  }
}());

Shopify는 모든 테마에 공통으로 적용되는 상품 옵션 이벤트를 정의하지 않습니다. 아래의 작은 어댑터를 활성 테마가 제공하는 이벤트 또는 콜백에 연결하세요.

테마 이벤트 어댑터 예제#

예제 이벤트를 활성 테마 API로 교체하세요. 일부 테마는 window.subscribe로 이벤트를 전달하고, 다른 테마는 DOM 이벤트를 발생시키거나 product-info를 갱신합니다.

js
// Example only: replace "variant:change" with your theme's event.
document.addEventListener('variant:change', function (event) {
  var variant = event.detail && event.detail.variant;
  var productContainer = event.target.closest('product-info') || document;

  document.dispatchEvent(new CustomEvent('idealhouse:variant-change', {
    detail: {
      container: productContainer,
      sku: variant && variant.sku
    }
  }));
});

5. 테마 스타일 추가#

assets/idealhouse-room-visualizer.css#

css
.idealhouse-view-button {
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 44px;
  padding: 0.75rem 1rem;
  border: 1px solid currentColor;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font: inherit;
}

.idealhouse-view-button[data-active="true"] {
  display: inline-flex;
  visibility: visible;
}

.idealhouse-view-button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

테마가 이러한 시각적 스타일을 재정의할 수 있습니다.

6. theme.liquid에 자산 포함#

layout/theme.liquid에 시각화 스타일시트와 스크립트를 포함하여 스타일을 적용하고 SDK 로더를 활성화하세요.

스타일시트 포함 (<head> 내부)#

liquid
{{ 'idealhouse-room-visualizer.css' | asset_url | stylesheet_tag }}

스타일이 올바르게 불러와지도록 layout/theme.liquid의 <head> 태그 안에 배치하세요.

스크립트 포함 (</body> 앞)#

liquid
<script src="{{ 'idealhouse-room-visualizer.js' | asset_url }}" defer="defer"></script>

페이지 렌더링을 차단하지 않도록 defer를 사용하고 layout/theme.liquid의 닫는 </body> 태그 바로 앞에 배치하세요.

이 로더 스크립트가 theme.liquid에 포함될 때까지 '내 방에서 보기' 버튼은 숨겨진 상태로 유지됩니다.

7. 운영 스토어에서 검증#

  1. 네트워크 패널에 sdk.js가 HTTP 200으로 불러와진 것으로 표시되는지 확인하세요.
  2. 직접 작성한 버튼의 data-product-code가 카탈로그 productCode와 정확히 일치하는지 확인하세요.
  3. 사용 가능한 상품에는 버튼이 표시되고 요건을 충족하지 못한 상품에는 숨겨진 상태로 유지되는지 확인하세요.
  4. 상품 옵션을 전환하면 data-product-code가 갱신되고 버튼이 다시 검증되는지 확인하세요.
  5. 컬렉션/검색, 상품 상세 페이지 데스크톱 및 모바일 배치가 있는 곳에서 올바르게 동작하는지 확인하세요.
  6. 버튼을 클릭하면 선택한 상품으로 ideal.house Viewer가 열리는지 확인하세요.