adstage
Web SDK廣告

廣告系統概觀

AdStage Web SDK 在網頁應用程式中支援 3 種類型的廣告。

🎯 支援的廣告類型

橫幅廣告 (Banner Ads)

以圖片為主的廣告,是最常見的形式。

AdStage.ads.banner('banner-container', {
  width: '100%',
  height: 250
});

特點:以圖片為主、自動調整尺寸、支援輪播

文字廣告 (Text Ads)

以文字為主的原生廣告,能與內容自然整合。

AdStage.ads.text('text-container');

特點:高度自動調整、限制行數、原生樣式

影片廣告 (Video Ads)

以影片為主的廣告,能帶來較高的參與度。

AdStage.ads.video('video-container', {
  width: 640,
  height: 360,
  autoplay: true,
  muted: true
});

特點:HTML5 影片、自動播放/靜音、行動裝置最佳化

🔄 基本使用流程

  1. 初始化 SDK - 以 AdStage.init() 進行設定
  2. 準備容器 - 在 HTML 中建立廣告顯示區域
  3. 請求廣告 - 呼叫 ads.banner()、ads.text()、ads.video()
  4. 自動渲染 - 在背景載入並顯示廣告
  5. 事件追蹤 - 自動收集曝光/點擊

📚 下一步

請確認各廣告類型的詳細用法:

🎯 支援的廣告類型

橫幅廣告 (Banner Ads)

以圖片為主的橫幅廣告,是最常見的網頁廣告形式。

// 基本橫幅廣告
AdStage.ads.banner('banner-container', {
  width: '100%',
  height: 250
});
 
// 點擊事件處理與進階選項
AdStage.ads.banner('banner-container', {
  width: '100%',
  height: 250,
  onClick: (adData) => {
    console.log('배너 광고 클릭:', adData);
  }
});

主要特點:

  • 動態調整尺寸(依圖片尺寸自動最佳化)
  • 背景載入,反應更快
  • 支援自動輪播(有多則廣告時)

文字廣告 (Text Ads)

以文字為主的原生廣告,能與內容自然融合。

// 基本文字廣告
AdStage.ads.text('text-container', {
  maxLines: 3
});
 
// 點擊事件處理
AdStage.ads.text('text-container', {
  maxLines: 3,
  onClick: (adData) => {
    console.log('텍스트 광고 클릭:', adData);
  }
});

主要特點:

  • 自動配合內容高度 (height: 'auto')
  • 與網站設計自然整合
  • 可限制最大行數

影片廣告 (Video Ads)

以影片為主的廣告,能帶來較高的參與度。

// 基本影片廣告(預設值:自動播放、靜音、隱藏控制項)
AdStage.ads.video('video-container', {
  width: 640,
  height: 360,
  autoplay: true,  // 預設值: true
  muted: true,     // 預設值: true
  controls: false  // 預設值: false
});
 
// 可由使用者控制的影片廣告
AdStage.ads.video('video-container', {
  width: 640,
  height: 360,
  autoplay: false,
  muted: false,
  controls: true,
  onClick: (adData) => {
    console.log('비디오 광고 클릭:', adData);
  }
});

主要特點:

  • 針對單一影片最佳化 (maxAds: 1)
  • HTML5 影片播放器
  • 支援行動裝置內嵌播放 (playsinline: true)
  • 預設啟用重複播放 (loop: true)

🔄 廣告顯示流程

graph TD
    A[SDK 初始化] --> B[偵測廣告容器]
    B --> C[請求廣告]
    C --> D[接收廣告回應]
    D --> E[算繪廣告]
    E --> F[傳送曝光事件]
    F --> G[追蹤使用者互動]
  1. 初始化:以 AdStage.init() 設定 SDK
  2. 準備容器:在 HTML 中建立要顯示廣告的元素
  3. 請求廣告:向伺服器請求廣告內容
  4. 渲染:將收到的廣告顯示在指定容器中
  5. 追蹤:自動追蹤曝光與點擊事件

⚙️ 設定選項

共用選項

所有廣告類型都可使用的選項:

選項類型預設值說明
onClickfunctionundefined廣告被點擊時的回呼函式
adIdstringundefined指定特定的廣告 ID
language'ko' | 'en' | 'ja' | 'zh'undefined語言篩選
deviceType'MOBILE' | 'DESKTOP'undefined裝置類型篩選
country'KR' | 'US' | 'JP' | 'CN' | 'DE'undefined國家篩選

橫幅廣告專用選項

選項類型預設值說明
widthstring | number'100%'廣告寬度
heightnumber250廣告高度(橫幅預設為 250px)
autoSlidebooleanfalse有多則廣告時自動輪播
slideIntervalnumber5000輪播間隔 (ms)

文字廣告專用選項

選項類型預設值說明
maxLinesnumber3最大行數
stylestring'default'樣式主題

參考:文字廣告的高度會依內容自動調整 (height: 'auto')。

影片廣告專用選項

選項類型預設值說明
widthnumber640影片寬度
heightnumber360影片高度
autoplaybooleantrue自動播放
mutedbooleantrue靜音
loopbooleantrue重複播放
controlsbooleanfalse顯示控制項
playsinlinebooleantrue內嵌播放(行動裝置)
hideControlsbooleanfalse隱藏所有控制項
customControlsobjectundefined細部控制項設定

影片自訂控制項選項

customControls: {
  hidePlayButton: boolean,      // 隱藏播放按鈕
  hideProgressBar: boolean,     // 隱藏進度列  
  hideCurrentTime: boolean,     // 隱藏目前時間
  hideRemainingTime: boolean,   // 隱藏剩餘時間
  hideVolumeSlider: boolean,    // 隱藏音量滑桿
  hideMuteButton: boolean,      // 隱藏靜音按鈕
  hideFullscreenButton: boolean // 隱藏全螢幕按鈕
}

範例:進階設定

// 以特定廣告 ID 顯示橫幅廣告
AdStage.ads.banner('my-banner', {
  width: '100%',
  height: 250,
  adId: 'specific-ad-123',
  language: 'ko',
  deviceType: 'DESKTOP',
  onClick: (adData) => {
    console.log('광고 클릭:', adData);
    // 自訂追蹤邏輯
  }
});
 
// 帶有自訂控制項的影片廣告
AdStage.ads.video('video-container', {
  width: 640,
  height: 360,
  autoplay: false,
  muted: false,
  controls: true,
  customControls: {
    hideFullscreenButton: true,
    hideVolumeSlider: false,
    hideProgressBar: false
  }
});

📊 效能最佳化

背景載入

SDK 會自動在背景載入廣告:

// 版位 ID 立即回傳,廣告於背景載入
const slotId = AdStage.ads.banner('banner-ad');
console.log('슬롯 생성됨:', slotId); // 立即執行
 
// 實際廣告會以非同步方式載入並渲染

自動清理 (Auto Cleanup)

從 DOM 中被移除的廣告容器會自動清理:

// 透過 MutationObserver 自動偵測並清理
// 開發者不需手動呼叫 destroy()
const slotId = AdStage.ads.banner('banner-ad');
 
// 容器從 DOM 移除時,版位也會自動清理
document.getElementById('banner-ad').remove();

重試邏輯

找不到容器時會自動重試:

// 即使容器尚未存在,也會逐步重試
const slotId = AdStage.ads.banner('not-yet-exists', {
  width: '100%',
  height: 250
});
 
// 之後容器被加入 DOM 時會自動顯示廣告
setTimeout(() => {
  const div = document.createElement('div');
  div.id = 'not-yet-exists';
  document.body.appendChild(div);
}, 1000);

🎨 樣式指南

CSS 類別

SDK 會自動加入的 CSS 類別:

/* 廣告容器 */
.adstage-ad {
  position: relative;
  overflow: hidden;
}
 
/* 載入狀態 */
.adstage-loading {
  opacity: 0.7;
}
 
/* 載入完成 */
.adstage-loaded {
  opacity: 1;
  transition: opacity 0.3s ease;
}
 
/* 錯誤狀態 */
.adstage-error {
  border: 1px solid #ff0000;
}

響應式設計

配合各種螢幕尺寸的廣告設定:

AdStage.ads.banner('responsive-banner', {
  width: '100%',
  height: window.innerWidth > 768 ? 250 : 100
});

實際使用範例

SDK 可在 JavaScript、React、Next.js 環境中使用。請透過實際範例了解實作方式。

JavaScript (UMD 方式)

這是在 HTML 檔案中直接載入 UMD 版本來使用的方法。

<!DOCTYPE html>
<html>
<head>
  <title>AdStage SDK Example</title>
</head>
<body>
  <!-- 廣告容器 -->
  <div id="banner-ad">배너 광고가 로드 중입니다...</div>
  <div id="text-ad">텍스트 광고가 로드 중입니다...</div>
  <div id="video-ad">비디오 광고가 로드 중입니다...</div>
 
  <!-- 載入 SDK -->
  <script src="https://unpkg.com/@adstage/web-sdk/dist/index.umd.js"></script>
  
  <script>
    // 初始化 SDK
    AdStage.init({
      apiKey: 'your-api-key',
      debug: true
    });
    
    // 建立廣告
    const bannerSlotId = AdStage.ads.banner('banner-ad', {
      width: '100%',
      height: 250,
      onClick: (adData) => console.log('배너 클릭:', adData)
    });
    
    const textSlotId = AdStage.ads.text('text-ad', {
      maxLines: 3,
      onClick: (adData) => console.log('텍스트 클릭:', adData)
    });
    
    const videoSlotId = AdStage.ads.video('video-ad', {
      width: 640,
      height: 360,
      autoplay: true,
      muted: true,
      controls: false,
      onClick: (adData) => console.log('비디오 클릭:', adData)
    });
  </script>
</body>
</html>

React(基本方式)

這是在 React 中直接使用 SDK 的方法。

import React, { useEffect, useRef } from 'react';
import { AdStage } from '@adstage/web-sdk';
 
function AdComponent() {
  const bannerRef = useRef(null);
  const textRef = useRef(null);
  const videoRef = useRef(null);
  const slotIdsRef = useRef({});
 
  useEffect(() => {
    // 初始化 SDK
    AdStage.init({
      apiKey: 'your-api-key',
      debug: true
    });
 
    // 建立廣告
    if (bannerRef.current) {
      slotIdsRef.current.banner = AdStage.ads.banner(bannerRef.current, {
        width: '100%',
        height: 250,
        onClick: (adData) => console.log('배너 클릭:', adData)
      });
    }
 
    if (textRef.current) {
      slotIdsRef.current.text = AdStage.ads.text(textRef.current, {
        maxLines: 3,
        onClick: (adData) => console.log('텍스트 클릭:', adData)
      });
    }
 
    if (videoRef.current) {
      slotIdsRef.current.video = AdStage.ads.video(videoRef.current, {
        width: 640,
        height: 360,
        autoplay: true,
        muted: true,
        controls: false,
        onClick: (adData) => console.log('비디오 클릭:', adData)
      });
    }
 
    // 清理函式
    return () => {
      Object.values(slotIdsRef.current).forEach(slotId => {
        if (slotId) AdStage.ads.destroy(slotId);
      });
    };
  }, []);
 
  return (
    <div>
      <h1>AdStage SDK - React 예제</h1>
      
      <div style={{ margin: '20px 0' }}>
        <h2>Banner Advertisement</h2>
        <div 
          ref={bannerRef}
          style={{ 
            minHeight: '100px',
            border: '2px dashed #ccc',
            borderRadius: '4px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
          }}
        >
          배너 광고가 로드 중입니다...
        </div>
      </div>
 
      <div style={{ margin: '20px 0' }}>
        <h2>Text Advertisement</h2>
        <div ref={textRef}>
          텍스트 광고가 로드 중입니다...
        </div>
      </div>
 
      <div style={{ margin: '20px 0' }}>
        <h2>Video Advertisement</h2>
        <div ref={videoRef}>
          비디오 광고가 로드 중입니다...
        </div>
      </div>
    </div>
  );
}
 
export default AdComponent;

Next.js(Provider 方式)

這是在 Next.js 中使用 AdStageProvider 的建議做法。

1. 在 _app.js 中設定 Provider

// pages/_app.js
import { AdStageProvider } from '@adstage/web-sdk';
 
export default function App({ Component, pageProps }) {
  return (
    <AdStageProvider
      config={{
        apiKey: 'your-api-key',
        debug: true
      }}
    >
      <Component {...pageProps} />
    </AdStageProvider>
  );
}

2. 在頁面中使用 useAdStageInstance Hook

// pages/index.js
import { useEffect, useRef } from 'react';
import { useAdStageInstance } from '@adstage/web-sdk';
 
export default function Home() {
  const adstage = useAdStageInstance();
  
  const bannerRef = useRef(null);
  const textRef = useRef(null);
  const videoRef = useRef(null);
  const slotIdsRef = useRef({});
 
  useEffect(() => {
    if (adstage) {
      loadAds();
    }
    
    return () => {
      // 元件卸載時清理
      Object.values(slotIdsRef.current).forEach(slotId => {
        if (slotId) adstage?.ads?.destroy(slotId);
      });
    };
  }, [adstage]);
 
  const loadAds = () => {
    // 橫幅廣告
    if (bannerRef.current) {
      slotIdsRef.current.banner = adstage.ads.banner(bannerRef.current, {
        width: '100%',
        height: 250,
        onClick: (adData) => console.log('배너 클릭:', adData)
      });
    }
    
    // 文字廣告
    if (textRef.current) {
      slotIdsRef.current.text = adstage.ads.text(textRef.current, {
        maxLines: 3,
        onClick: (adData) => console.log('텍스트 클릭:', adData)
      });
    }
    
    // 影片廣告
    if (videoRef.current) {
      slotIdsRef.current.video = adstage.ads.video(videoRef.current, {
        width: 640,
        height: 360,
        autoplay: true,
        muted: true,
        controls: false,
        onClick: (adData) => console.log('비디오 클릭:', adData)
      });
    }
  };
 
  return (
    <div style={{ fontFamily: 'Arial, sans-serif', margin: '20px' }}>
      <h1>AdStage SDK - Next.js 광고 예제</h1>
      
      {/* 橫幅廣告 */}
      <div style={{ margin: '40px 0', padding: '20px', border: '1px solid #ddd' }}>
        <h2>Banner Advertisement</h2>
        <div 
          ref={bannerRef}
          style={{ 
            minHeight: '100px',
            border: '2px dashed #ccc',
            borderRadius: '4px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
          }}
        >
          배너 광고가 로드 중입니다...
        </div>
      </div>
      
      {/* 文字廣告 */}
      <div style={{ margin: '40px 0', padding: '20px', border: '1px solid #ddd' }}>
        <h2>Text Advertisement</h2>
        <div 
          ref={textRef}
          style={{ 
            backgroundColor: 'rgba(34, 197, 94, 0.1)',
            borderRadius: '12px',
            border: '1px solid rgba(34, 197, 94, 0.2)',
            padding: '16px',
            minHeight: '80px'
          }}
        >
          텍스트 광고가 로드 중입니다...
        </div>
      </div>
      
      {/* 影片廣告 */}
      <div style={{ margin: '40px 0', padding: '20px', border: '1px solid #ddd' }}>
        <h2>Video Advertisement</h2>
        <div 
          ref={videoRef}
          style={{ 
            minHeight: '100px',
            border: '2px dashed #ccc',
            borderRadius: '4px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
          }}
        >
          비디오 광고가 로드 중입니다...
        </div>
      </div>
    </div>
  );
}

目錄