adstage
Web SDK广告

广告系统概览

AdStage Web SDK 在 Web 应用中支持 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 钩子

// 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>
  );
}

目录