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 全局初始化只配置一次 SDKApp/RootLayout
钩子(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. 按实现策略,原有广告位会被移除,并以最后一次调用为准保留。

目录