adstage
Web SDK廣告

共用功能

本文將過去在各廣告類型文件中重複出現的「共用概念」集中於一處,方便維護,同時讓各廣告類型文件能專注於 各自類型專屬的功能。

🧱 基本結構 & 共用呼叫模式

// 1) SDK 初始化(應用程式全域僅一次)
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 AdSlot {
  id: string;                 // 版位 ID (slotId)
  containerId: string;        // 容器 DOM id
  adType: 'BANNER' | 'TEXT' | 'VIDEO' | 'NATIVE' | 'INTERSTITIAL' | 'POPUP';
  width: number | string;     // 數字(px) 或字串('100%' 等)
  height: number | string;    // 數字(px) 或字串('auto' 等)
  isLoaded: boolean;          // 廣告是否載入完成
  isVisible: boolean;         // 曝光狀態
  refreshRate: number;        // 自動重新整理週期(秒)
  lazyLoad: boolean;          // 是否延遲載入
  targeting: Record<string, any>;
 
  // 版位方法
  load(): Promise<Advertisement | null>;
  render(ad: Advertisement): void;
  refresh(): Promise<void>;
  destroy(): void;
}

🚀 效能 & 最佳化的共用策略

策略說明備註
背景載入非同步載入,不阻擋初次渲染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
Hook(useAdStageInstance)安全地存取 SDKCSR 元件
在 useEffect 中 cleanup確保執行 destroy明確界定版位生命週期
骨架畫面樣式自訂 .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 });

點擊掛鉤(onClick 回呼)

SDK 不會發出 adstage:ad:loaded / adstage:ad:error 這類 DOM CustomEvent。若需要廣告互動掛鉤,請在建立版位時傳入 onClick 回呼。

AdStage.ads.banner('banner-container', {
  width: '100%',
  height: 250,
  onClick: (adData) => {
    console.log('광고 클릭됨:', adData);
    // 추가 추적/라우팅 로직
  }
});

確認載入狀態

是否載入完成,可透過輪詢版位的 isLoaded 欄位來確認(開啟除錯模式後,載入成功/失敗會輸出到主控台)。

const slotId = AdStage.ads.banner('banner-container', { width: '100%', height: 250 });
 
const timer = setInterval(() => {
  const slot = AdStage.ads.getSlotById(slotId);
  if (slot?.isLoaded) {
    console.log('로드 완료:', slot);
    clearInterval(timer);
  }
}, 200);

狀態診斷工具

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

🔐 安全 & 最佳實務

主題建議事項
API Key可以公開露出,但建議使用權限最小化的金鑰
事件追蹤在 onClick 中額外追蹤時,建議非同步送出後再導頁
錯誤因應以除錯模式的主控台記錄與版位的 isLoaded 狀態診斷載入失敗
重試策略容器延遲插入的情況 SDK 會自行處理 → 避免濫用額外的 setTimeout

❓FAQ(共用)

Q. 一定要呼叫 destroy() 嗎?
A. 多數情況並不需要。SDK 會自動偵測 DOM 被移除。不過若要把同一容器立刻挪作他用,建議手動呼叫 destroy()。

Q. 廣告沒有出現,但 slotId 有回傳。
A. 可能正在非同步載入,或被篩選條件(adId / language / deviceType / country)過濾掉了。請啟用除錯模式並確認事件記錄。

Q. 在 SSR(Next.js)中會於伺服器端渲染嗎?
A. 不會。廣告渲染只在用戶端執行。請在 use client 元件內部呼叫。

Q. 對同一位置連續呼叫會如何?
A. 依實作策略,既有版位會被移除,並以最後一次呼叫為準保留。

目錄