StageUp
웹 SDK광고

공통 기능

이 문서는 개별 광고 타입 문서에 반복되던 "공통 개념"을 한 곳에 모아 유지보수를 쉽게 하고, 광고 타입 문서는 각 타입 고유 기능에 집중할 수 있도록 합니다.

🧱 기본 구조 & 공통 호출 패턴

// 1) SDK 초기화 (앱 전역 1회)
AdStage.init({
  apiKey: 'your-api-key',
  debug: process.env.NODE_ENV === 'development'
});
 
// 2) 컨테이너 DOM 준비 후 호출 (id 또는 Element 모두 허용)
AdStage.ads.banner('banner-container', { /* 옵션 */ });
// AdStage.ads.text(element, { /* 옵션 */ });
// AdStage.ads.video('video-wrapper', { /* 옵션 */ });
 
// 3) 필요 시 수동 제거 (대부분 필요 없음: 자동 정리 지원)
AdStage.ads.destroy(slotId);

React / Next.js Provider 공통 패턴

import { AdStageProvider, useAdStageInstance } from '@adstage/web-sdk';
 
// layout / root
<AdStageProvider config={{ apiKey: process.env.NEXT_PUBLIC_ADSTAGE_API_KEY, debug: true }}>
  {children}
</AdStageProvider>
 
// 개별 컴포넌트
function BannerSlot() {
  const adstage = useAdStageInstance();
  const ref = useRef(null);
  useEffect(() => {
    if (!adstage || !ref.current) return;
    const id = adstage.ads.banner(ref.current, { width: '100%', height: 250 });
    return () => adstage.ads.destroy(id);
  }, [adstage]);
  return <div ref={ref} style={{ height: 250 }} />;
}

⚙️ 공통 옵션 정리

옵션타입설명적용 대상
onClickfunction(adData)광고 클릭 시 콜백전 타입
adIdstring특정 광고 강제 지정전 타입
language'ko' | 'en' | 'ja' | 'zh'언어 필터전 타입
deviceType'MOBILE' | 'DESKTOP'디바이스 필터전 타입
country국가 코드 (ISO2)국가 필터전 타입

광고 타입별 고유 옵션은 각 문서(배너/텍스트/비디오) 참조.

🔄 라이프사이클 & 내부 동작

graph TD
  A[init 호출] --> B[slot 함수 호출]
  B --> C[컨테이너 탐색/재시도]
  C --> D[서버 광고 요청]
  D --> E[비동기 로딩]
  E --> F[렌더링]
  F --> G[노출 추적]
  G --> H[클릭/상호작용 추적]

주요 특성

  • 즉시 반환형: slotId는 서버 응답 전 즉시 반환 ⇒ UI 블로킹 없음
  • 지연 컨테이너 대응: 컨테이너가 아직 DOM에 없어도 일정 시간 재시도 후 붙으면 렌더링
  • MutationObserver 기반 자동 정리: DOM 제거 시 destroy() 자동 실행
  • 다중 광고 안전: 동일 컨테이너 중복 호출 시 최신 호출만 유효 (구현체 정책)

🧪 슬롯 관리 API

// 모든 슬롯 정보
const all = AdStage.ads.getAllSlots();
 
// 특정 슬롯 조회
const slot = AdStage.ads.getSlotById(slotId);
 
// 수동 제거 (필요한 경우)
AdStage.ads.destroy(slotId);

슬롯 객체(예시 형태):

interface AdStageSlot {
  id: string;
  type: 'banner' | 'text' | 'video';
  container: HTMLElement;
  status: 'pending' | 'loading' | 'loaded' | 'error' | 'destroyed';
  meta?: Record<string, any>;
}

🚀 성능 & 최적화 공통 전략

전략설명비고
백그라운드 로딩비동기 로딩으로 초기 렌더 차단 없음slotId 즉시 사용 가능
지연 컨테이너 지원DOM 나중 삽입 케이스 자동 처리초기화 코드 단순화
자동 정리메모리/이벤트 릭 방지SPA 전환 시 유용
최소 DOM 조작컨테이너 내부 DOM만 업데이트부모 레이아웃 영향 최소화
타입별 사이즈 최적화배너/비디오는 크기 지정, 텍스트는 높이 자동CLS 감소

반응형 패턴 공통 템플릿

function selectDeviceType() {
  return window.innerWidth <= 768 ? 'MOBILE' : 'DESKTOP';
}
 
const base = { language: 'ko', deviceType: selectDeviceType() };
const id = AdStage.ads.banner('rwd-banner', { width: '100%', height: 250, ...base });
 
window.addEventListener('resize', () => {
  AdStage.ads.destroy(id);
  const next = AdStage.ads.banner('rwd-banner', { width: '100%', height: 250, deviceType: selectDeviceType() });
});

📦 React / Next.js 권장 패턴 요약

패턴설명사용 시점
Provider 전역 초기화한 번만 SDK 설정App/RootLayout
훅(useAdStageInstance)안전한 SDK accessCSR 컴포넌트
cleanup in useEffectdestroy 보장슬롯 수명 명확화
Skeleton 스타일.adstage-loading 상태 커스터마이즈UX 개선

🎨 공통 CSS 클래스

.adstage-ad, .adstage-text-ad, .adstage-video-ad { position: relative; overflow: hidden; }
.adstage-loading { opacity: .6; transition: opacity .15s; }
.adstage-loaded { opacity: 1; }
.adstage-error { outline: 1px solid #f87171; }

타입별 추가 스타일은 개별 문서 참조.

🛠 디버깅 & 모니터링

디버그 모드 활성화

AdStage.init({ apiKey: 'your-api-key', debug: true });

커스텀 이벤트 수신

document.addEventListener('adstage:ad:loaded', e => {
  console.log('로드 완료:', e.detail);
});
 
document.addEventListener('adstage:ad:error', e => {
  console.error('로드 실패:', e.detail);
});

상태 진단 유틸

function dumpAdStage() {
  const slots = AdStage.ads.getAllSlots();
  console.table(slots.map(s => ({ id: s.id, type: s.type, status: s.status })));
}

🔐 안전 & 베스트 프랙티스

주제권장 사항
API Key퍼블릭 노출 가능하나 권한 최소화된 키 사용
이벤트 추적onClick에서 추가 추적 시 비동기 전송 후 라우팅 권장
오류 대응adstage:ad:error 이벤트 로깅/알림 연동
재시도 정책컨테이너 지연 삽입 케이스 자체 처리 → 추가 setTimeout 남용 지양

❓FAQ (공통)

Q. destroy()를 꼭 호출해야 하나요?
A. 대부분 필요 없습니다. DOM 제거 감지가 자동 수행됩니다. 다만 동일 컨테이너를 즉시 다른 용도로 재사용할 경우 수동 destroy()를 권장합니다.

Q. 광고가 안 뜨는데 slotId는 나옵니다.
A. 비동기 로딩 중이거나 필터(adId / language / deviceType / country)에 걸러졌을 수 있습니다. 디버그 모드를 활성화하고 이벤트 로그를 확인하세요.

Q. SSR(Next.js)에서 서버 측에서 렌더됩니까?
A. 아니요. 광고 렌더는 클라이언트 측에서만 수행됩니다. use client 컴포넌트 내부에서 호출하세요.

Q. 동일 위치에 연속 호출 시 어떻게 됩니까?
A. 구현 정책에 따라 기존 슬롯이 제거되고 마지막 호출 기준으로 유지됩니다.

목차