구현 방법
네이티브 광고는 앱의 디자인에 맞게 커스텀 UI로 광고를 표시할 수 있습니다.
| 방식 | 설명 | 추천 |
|---|
| 기본 템플릿 | SDK 제공 템플릿 사용 | 빠른 구현 |
| 커스텀 UI | 직접 UI 구성 | 디자인 맞춤 필요 시 |
개발 환경에서는 테스트 유닛 ID를 사용하세요: PUBLIC_TEST_UNIT_ID_NATIVE
기본 템플릿
배너 광고와 동일한 방식으로 기본 템플릿을 사용할 수 있습니다. SDK가 제공하는 템플릿에 이미지, 텍스트가 자동으로 렌더링됩니다.
function NativeAd() {
return <div data-adrop-unit="YOUR_NATIVE_UNIT_ID" />;
}
기본 템플릿은 광고주 프로필 섹션을 지원하지 않습니다. 광고주 프로필을 표시하려면 커스텀 UI를 사용하세요.
커스텀 UI
1. Data Attributes 방식
data-adrop-render="custom" 속성을 추가하고, 내부 요소에 data-adrop-native 속성으로 필드를 바인딩합니다.
function CustomNativeAd() {
return (
<div
data-adrop-unit="YOUR_NATIVE_UNIT_ID"
data-adrop-render="custom"
data-adrop-entire-click="true"
className="native-ad"
>
{/* 광고주 프로필 */}
<div className="ad-profile">
<img data-adrop-native="profile.displayLogo" alt="광고주" />
<span data-adrop-native="profile.displayName"></span>
</div>
{/* 광고 콘텐츠 */}
<h3 data-adrop-native="headline"></h3>
<img data-adrop-native="asset" alt="광고" />
<p data-adrop-native="body"></p>
{/* 추가 텍스트 항목 */}
<span data-adrop-native="extra.price"></span>
{/* CTA 버튼 */}
<button data-adrop-native="callToAction"></button>
</div>
);
}
Data Attributes
전체 영역 클릭 활성화
false: 텍스트/이미지만 클릭 가능, 광고주 프로필 클릭 시 프로필 링크로 이동
true: 컨테이너 전체 클릭 가능, 모든 클릭이 광고 목적지로 이동
2. renderAd 방식
광고 로드 타이밍을 직접 제어하고 싶을 때 사용합니다.
import { useEffect, useRef } from 'react';
import Adrop from '@adrop/ads-web-sdk';
function CustomNativeAd() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const adrop = Adrop.instance();
if (containerRef.current) {
adrop.renderAd(containerRef.current, {
unit: 'YOUR_NATIVE_UNIT_ID',
contextId: 'YOUR_CONTEXT_ID',
theme: 'light',
trackMode: 1, // 커스텀 UI 사용 시 필수
isEntireClick: true // 전체 영역 클릭 활성화
});
}
}, []);
return (
<div ref={containerRef} className="native-ad">
<div className="ad-profile">
<img data-adrop-native="profile.displayLogo" alt="광고주" />
<span data-adrop-native="profile.displayName"></span>
</div>
<h3 data-adrop-native="headline"></h3>
<img data-adrop-native="asset" alt="광고" />
<p data-adrop-native="body"></p>
<button data-adrop-native="callToAction"></button>
</div>
);
}
renderAd 옵션
사용자 식별자 (SDK 설정 값을 개별 지면에서 오버라이드할 때 사용)
필드 바인딩
data-adrop-native 속성으로 광고 데이터를 UI 요소에 바인딩합니다.
| 필드 | 설명 | 요소 타입 |
|---|
profile.displayLogo | 광고주 로고 URL | <img> |
profile.displayName | 광고주 이름 | 텍스트 |
headline | 광고 제목 | 텍스트 |
body | 광고 설명 | 텍스트 |
asset | 메인 이미지 URL | <img> |
callToAction | CTA 버튼 텍스트 | 텍스트 |
extra.{key} | 추가 텍스트 항목 | 텍스트 |
extra.{key}는 애드컨트롤 콘솔에서 설정한 추가 텍스트 항목의 ID입니다. 필수로 설정하지 않았다면 비어있을 수 있습니다.
광고주 프로필(profile.displayLogo, profile.displayName)을 표시하려면 애드컨트롤 콘솔에서 해당 광고 유닛의 광고주 프로필 표시를 활성화해야 합니다.
광고 크기
커스텀 UI의 크기는 자유롭게 설정할 수 있습니다.
| 구분 | 크기 설정 | 정렬 |
|---|
| 직광고 | 반응형 지원 | 가로/세로 가운데 |
| 백필 광고 | 초기 너비 맞춤, 높이 필수 | 가로 가운데 |
백필 광고는 컨테이너 크기에 맞는 소재를 요청합니다. 적절한 크기를 지정하세요.
requestAd로 데이터만 가져오기
UI를 완전히 직접 제어하고 싶다면 requestAd로 광고 데이터만 가져올 수 있습니다.
import { useState, useEffect } from 'react';
import Adrop from '@adrop/ads-web-sdk';
function NativeAd() {
const [adData, setAdData] = useState<AdData | null>(null);
useEffect(() => {
async function loadAd() {
const adrop = Adrop.instance();
const response = await adrop.requestAd({
unit: 'YOUR_NATIVE_UNIT_ID',
trackMode: 1
});
if (response.code === 0 && response.result) {
setAdData(response.result);
}
}
loadAd();
}, []);
if (!adData) return null;
return (
<div className="native-ad">
<div className="ad-header">
{adData.profile?.displayLogo && (
<img src={adData.profile.displayLogo} alt="광고주" />
)}
<span>{adData.profile?.displayName}</span>
</div>
<h3>{adData.headline}</h3>
{adData.asset && <img src={adData.asset} alt="광고" />}
<p>{adData.body}</p>
<a href={adData.destinationURL} target="_blank" rel="noopener noreferrer">
{adData.callToAction}
</a>
</div>
);
}
requestAd 사용 시 노출/클릭 추적을 직접 구현해야 합니다. 또한 이 방식에서는 백필 광고가 지원되지 않습니다. 특별한 경우가 아니라면 renderAd를 권장합니다.
AdropAdResponse
requestAd()의 반환값입니다.
| 필드 | 타입 | 설명 |
|---|
code | number | 응답 코드 (0: 성공, 4000-4003: 에러) |
msg | string | 응답 메시지 |
result | AdData | 광고 데이터 (성공 시에만 존재) |
AdData
광고 데이터 객체입니다. 이벤트 핸들러에서도 동일한 구조로 전달됩니다. 자세한 내용은 레퍼런스 > AdData를 참고하세요.
| 필드 | 타입 | 설명 |
|---|
format | string | 광고 포맷 (banner, nativeAd, backfill) |
unit | string | 유닛 ID |
headline | string | 광고 제목 |
body | string | 광고 설명 |
callToAction | string | CTA 버튼 텍스트 |
asset | string | 메인 이미지 URL |
destinationURL | string | 클릭 시 이동할 URL |
profile.displayLogo | string | 광고주 로고 URL |
profile.displayName | string | 광고주 이름 |
profile.link | string | 광고주 프로필 링크 |
extra | Record<string, string> | 추가 텍스트 항목 |
이벤트 처리
import { useEffect, useRef } from 'react';
import Adrop from '@adrop/ads-web-sdk';
function NativeAd({ unitId }: { unitId: string }) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const adrop = Adrop.instance();
const filter = { unit: unitId };
const handleReceived = (unit: string, adData: any) => {
console.log('광고 수신:', adData);
};
const handleNoFill = (unit: string) => {
console.warn('광고 없음:', unit);
};
const handleFailed = (unit: string) => {
console.error('광고 실패:', unit);
};
const handleImpression = (unit: string) => {
console.log('광고 노출:', unit);
};
const handleClicked = (unit: string) => {
console.log('광고 클릭:', unit);
};
adrop.on(Adrop.Events.AD_RECEIVED, handleReceived, filter);
adrop.on(Adrop.Events.AD_NO_FILL, handleNoFill, filter);
adrop.on(Adrop.Events.AD_FAILED, handleFailed, filter);
adrop.on(Adrop.Events.AD_IMPRESSION, handleImpression, filter);
adrop.on(Adrop.Events.AD_CLICKED, handleClicked, filter);
if (containerRef.current) {
adrop.renderAd(containerRef.current, {
unit: unitId,
trackMode: 1,
isEntireClick: true
});
}
return () => {
adrop.off(Adrop.Events.AD_RECEIVED, handleReceived);
adrop.off(Adrop.Events.AD_NO_FILL, handleNoFill);
adrop.off(Adrop.Events.AD_FAILED, handleFailed);
adrop.off(Adrop.Events.AD_IMPRESSION, handleImpression);
adrop.off(Adrop.Events.AD_CLICKED, handleClicked);
};
}, [unitId]);
return (
<div ref={containerRef} className="native-ad">
<div className="ad-profile">
<img data-adrop-native="profile.displayLogo" alt="광고주" />
<span data-adrop-native="profile.displayName"></span>
</div>
<h3 data-adrop-native="headline"></h3>
<img data-adrop-native="asset" alt="광고" />
<p data-adrop-native="body"></p>
<button data-adrop-native="callToAction"></button>
</div>
);
}
지원 이벤트
| 이벤트 | 상수 | 설명 |
|---|
| 광고 수신 | AD_RECEIVED | 광고 요청 성공 |
| 광고 없음 | AD_NO_FILL | 송출 가능한 직광고 없음 |
| 요청 실패 | AD_FAILED | 광고 요청 실패 |
| 노출 | AD_IMPRESSION | 광고 노출 기록됨 |
| 클릭 | AD_CLICKED | 사용자가 광고 클릭 |
| 백필 없음 | AD_BACKFILL_NO_FILL | 백필 광고 없음 |