StageUp
Web SDKAdvertisements

Advertising System Overview

The AdStage Web SDK supports three types of ads in web applications.

๐ŸŽฏ Supported Ad Types

Image-based ads, the most common format.

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

Features: Image-based, automatic resizing, slide support

Text Ads

Text-based native ads that integrate naturally with your content.

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

Features: Automatic height adjustment, line count limit, native styling

Video Ads

Video-based ads that deliver high engagement.

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

Features: HTML5 video, autoplay/mute, mobile optimization

๐Ÿ”„ Basic Usage Flow

  1. Initialize the SDK - Configure with AdStage.init()
  2. Prepare a container - Create an ad display area in your HTML
  3. Request an ad - Call ads.banner(), ads.text(), or ads.video()
  4. Automatic rendering - Ads load and display in the background
  5. Event tracking - Impressions/clicks are collected automatically

๐Ÿ“š Next Steps

Check out the detailed usage guide for each ad type:

๐ŸŽฏ Supported Ad Types

Image-based banner ads, the most common form of web advertising.

// ๊ธฐ๋ณธ ๋ฐฐ๋„ˆ ๊ด‘๊ณ 
AdStage.ads.banner('banner-container', {
  width: '100%',
  height: 250
});
 
// ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐ ๊ณ ๊ธ‰ ์˜ต์…˜
AdStage.ads.banner('banner-container', {
  width: '100%',
  height: 250,
  onClick: (adData) => {
    console.log('๋ฐฐ๋„ˆ ๊ด‘๊ณ  ํด๋ฆญ:', adData);
  }
});

Key features:

  • Dynamic resizing (automatically optimized based on image size)
  • Fast response with background loading
  • Automatic slide support (for multiple ads)

Text Ads

Text-based native ads that blend naturally with your content.

// ๊ธฐ๋ณธ ํ…์ŠคํŠธ ๊ด‘๊ณ 
AdStage.ads.text('text-container', {
  maxLines: 3
});
 
// ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
AdStage.ads.text('text-container', {
  maxLines: 3,
  onClick: (adData) => {
    console.log('ํ…์ŠคํŠธ ๊ด‘๊ณ  ํด๋ฆญ:', adData);
  }
});

Key features:

  • Automatically fits to content height (height: 'auto')
  • Natural integration with your site design
  • Maximum line count limit available

Video Ads

Video-based ads that deliver high engagement.

// ๊ธฐ๋ณธ ๋น„๋””์˜ค ๊ด‘๊ณ  (๊ธฐ๋ณธ๊ฐ’: ์ž๋™์žฌ์ƒ, ์Œ์†Œ๊ฑฐ, ์ปจํŠธ๋กค ์ˆจ๊น€)
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);
  }
});

Key features:

  • Optimized for a single video (maxAds: 1)
  • HTML5 video player
  • Mobile inline playback support (playsinline: true)
  • Loop playback enabled by default (loop: true)

๐Ÿ”„ Ad Display Process

graph TD
    A[SDK ์ดˆ๊ธฐํ™”] --> B[๊ด‘๊ณ  ์ปจํ…Œ์ด๋„ˆ ํƒ์ง€]
    B --> C[๊ด‘๊ณ  ์š”์ฒญ]
    C --> D[๊ด‘๊ณ  ์‘๋‹ต ์ˆ˜์‹ ]
    D --> E[๊ด‘๊ณ  ๋ Œ๋”๋ง]
    E --> F[๋…ธ์ถœ ์ด๋ฒคํŠธ ์ „์†ก]
    F --> G[์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ ์ถ”์ ]
  1. Initialization: Configure the SDK with AdStage.init()
  2. Container preparation: Create the element where the ad will be displayed in your HTML
  3. Ad request: Request ad content from the server
  4. Rendering: Display the received ad in the specified container
  5. Tracking: Automatically track impression and click events

โš™๏ธ Configuration Options

Common Options

Options available for all ad types:

OptionTypeDefaultDescription
onClickfunctionundefinedCallback function on ad click
adIdstringundefinedSpecify a particular ad ID
language'ko' | 'en' | 'ja' | 'zh'undefinedLanguage filter
deviceType'MOBILE' | 'DESKTOP'undefinedDevice type filter
country'KR' | 'US' | 'JP' | 'CN' | 'DE'undefinedCountry filter
OptionTypeDefaultDescription
widthstring | number'100%'Ad width
heightnumber250Ad height (banner defaults to 250px)
autoSlidebooleanfalseAutomatic slide for multiple ads
slideIntervalnumber5000Slide interval (ms)

Text Ad-Specific Options

OptionTypeDefaultDescription
maxLinesnumber3Maximum number of lines
stylestring'default'Style theme

Note: The height of text ads is automatically adjusted based on content (height: 'auto').

Video Ad-Specific Options

OptionTypeDefaultDescription
widthnumber640Video width
heightnumber360Video height
autoplaybooleantrueAutoplay
mutedbooleantrueMute
loopbooleantrueLoop playback
controlsbooleanfalseShow controls
playsinlinebooleantrueInline playback (mobile)
hideControlsbooleanfalseHide all controls
customControlsobjectundefinedDetailed control settings

Video Custom Control Options

customControls: {
  hidePlayButton: boolean,      // ์žฌ์ƒ ๋ฒ„ํŠผ ์ˆจ๊ธฐ๊ธฐ
  hideProgressBar: boolean,     // ์ง„ํ–‰๋ฐ” ์ˆจ๊ธฐ๊ธฐ  
  hideCurrentTime: boolean,     // ํ˜„์žฌ ์‹œ๊ฐ„ ์ˆจ๊ธฐ๊ธฐ
  hideRemainingTime: boolean,   // ๋‚จ์€ ์‹œ๊ฐ„ ์ˆจ๊ธฐ๊ธฐ
  hideVolumeSlider: boolean,    // ๋ณผ๋ฅจ ์Šฌ๋ผ์ด๋” ์ˆจ๊ธฐ๊ธฐ
  hideMuteButton: boolean,      // ์Œ์†Œ๊ฑฐ ๋ฒ„ํŠผ ์ˆจ๊ธฐ๊ธฐ
  hideFullscreenButton: boolean // ์ „์ฒดํ™”๋ฉด ๋ฒ„ํŠผ ์ˆจ๊ธฐ๊ธฐ
}

Example: Advanced Configuration

// ํŠน์ • ๊ด‘๊ณ  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
  }
});

๐Ÿ“Š Performance Optimization

Background Loading

The SDK automatically loads ads in the background:

// ์Šฌ๋กฏ ID๋Š” ์ฆ‰์‹œ ๋ฐ˜ํ™˜, ๊ด‘๊ณ ๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋กœ๋“œ
const slotId = AdStage.ads.banner('banner-ad');
console.log('์Šฌ๋กฏ ์ƒ์„ฑ๋จ:', slotId); // ์ฆ‰์‹œ ์‹คํ–‰
 
// ์‹ค์ œ ๊ด‘๊ณ ๋Š” ๋น„๋™๊ธฐ๋กœ ๋กœ๋“œ๋˜์–ด ๋ Œ๋”๋ง๋จ

Auto Cleanup

Ad containers removed from the DOM are cleaned up automatically:

// MutationObserver๋ฅผ ํ†ตํ•œ ์ž๋™ ๊ฐ์ง€ ๋ฐ ์ •๋ฆฌ
// ๊ฐœ๋ฐœ์ž๊ฐ€ ์ˆ˜๋™์œผ๋กœ destroy()๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š” ์—†์Œ
const slotId = AdStage.ads.banner('banner-ad');
 
// DOM์—์„œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ œ๊ฑฐ๋˜๋ฉด ์ž๋™์œผ๋กœ ์Šฌ๋กฏ๋„ ์ •๋ฆฌ๋จ
document.getElementById('banner-ad').remove();

Retry Logic

Automatically retries when the container is not found:

// ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„์ง ์กด์žฌํ•˜์ง€ ์•Š์•„๋„ ์ ์ง„์ ์œผ๋กœ ์žฌ์‹œ๋„
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);

๐ŸŽจ Styling Guide

CSS Classes

CSS classes the SDK adds automatically:

/* ๊ด‘๊ณ  ์ปจํ…Œ์ด๋„ˆ */
.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;
}

Responsive Design

Ad settings tailored to various screen sizes:

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

Real-World Usage Examples

The SDK can be used in JavaScript, React, and Next.js environments. Learn how to implement it through real-world examples.

JavaScript (UMD Approach)

How to load and use the UMD build directly in an HTML file.

<!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 (Basic Approach)

How to use the SDK directly in React.

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 Approach)

The recommended approach using AdStageProvider in Next.js.

1. Set up the Provider in _app.js

// 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. Use the useAdStageInstance hook in a page

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

Table of Contents