본문으로 건너뛰기

컨텍스추얼 타겟팅 예제

컨텍스추얼 타겟팅을 적용한 전체 예제 코드입니다.

1. 기본 예제​

  • 첫 화면 광고 슬롯은 즉시 요청하고, 본문 아래 광고 슬롯은 분석이 끝난 뒤 context를 포함하여 요청합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>컨텍스추얼 타겟팅 예제</title>
<script async src="https://sdk.naverads.net/libs/glad/prod/gfp-core.js"></script>
<script>
window.gladsdk = window.gladsdk || { cmd: [] };
</script>
<script defer src="https://sdk.naverads.net/libs/ctx-check/ctx-sdk.js" data-root="#postViewArea"></script>
</head>

<body>
<div id="ad-top"></div>
<article id="postViewArea">…본문…</article>
<div id="ad-mid"></div>
<div id="ad-bottom"></div>

<script>
var TOP_UNIT_ID = 'TOP_UNIT_ID';
var BOTTOM_UNIT_ID = 'BOTTOM_UNIT_ID';

// 상단: 즉시 요청
window.gladsdk.cmd.push(function () {
window.gladsdk.defineAdSlot({ adUnitId: TOP_UNIT_ID, adSlotElementId: 'ad-top' });
window.gladsdk.displayAd('ad-top');
});

// 하단: 분석 완료 후 요청
document.addEventListener('DOMContentLoaded', function () {
var analysis = window.gladsdk.CtxCheck
? window.gladsdk.CtxCheck.recommend({ idle: true }).catch(function () { return null; })
: Promise.resolve(null); // 스크립트 미로드 시 context 없이 요청

analysis.then(function (res) {
window.gladsdk.cmd.push(function () {
['ad-mid', 'ad-bottom'].forEach(function (id) {
var adSlotInfo = {
adUnitId: BOTTOM_UNIT_ID,
adSlotElementId: id,
keyword: 'GV90', // 매체 주입 키워드 (선택)
};
if (res && res.context) {
adSlotInfo.context = res.context;
}
window.gladsdk.defineAdSlot(adSlotInfo);
window.gladsdk.displayAd(id);
});
});
});
});
</script>
</body>
</html>

2. 중복 제어 적용 예제​

  • 1번 예제에 광고 중복 제어를 적용한 예제입니다. 모든 광고 슬롯을 하나의 중복 제어 매니저로 요청합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>컨텍스추얼 타겟팅 + 중복 제어 예제</title>
<script async src="https://sdk.naverads.net/libs/glad/prod/gfp-core.js"></script>
<script>
window.gladsdk = window.gladsdk || { cmd: [] };
</script>
<script defer src="https://sdk.naverads.net/libs/ctx-check/ctx-sdk.js" data-root="#postViewArea"></script>
</head>

<body>
<div id="ad-top"></div>
<article id="postViewArea">…본문…</article>
<div id="ad-mid"></div>
<div id="ad-bottom"></div>

<script>
var TOP_UNIT_ID = 'TOP_UNIT_ID';
var BOTTOM_UNIT_ID = 'BOTTOM_UNIT_ID';
var adDedupManager; // 상단, 하단 광고 슬롯이 공유하는 중복 제어 매니저

// 상단: 즉시 요청
window.gladsdk.cmd.push(function () {
adDedupManager = window.gladsdk.setAdDeduplication('dedupReqId', 2); // 광고 슬롯 수 - 1
var topAdSlot = window.gladsdk.defineAdSlot({ adUnitId: TOP_UNIT_ID, adSlotElementId: 'ad-top' });
adDedupManager.displayAds([topAdSlot]);
});

// 하단: 분석 완료 후 요청
document.addEventListener('DOMContentLoaded', function () {
var analysis = window.gladsdk.CtxCheck
? window.gladsdk.CtxCheck.recommend({ idle: true }).catch(function () { return null; })
: Promise.resolve(null); // 스크립트 미로드 시 context 없이 요청

analysis.then(function (res) {
window.gladsdk.cmd.push(function () {
var adSlots = ['ad-mid', 'ad-bottom'].map(function (id) {
var adSlotInfo = {
adUnitId: BOTTOM_UNIT_ID,
adSlotElementId: id,
keyword: 'GV90', // 매체 주입 키워드 (선택)
};
if (res && res.context) {
adSlotInfo.context = res.context;
}
return window.gladsdk.defineAdSlot(adSlotInfo);
});
adDedupManager.displayAds(adSlots); // 상단 광고를 제외 기준으로 ad-mid, ad-bottom 순서대로 요청
});
});
});
</script>
</body>
</html>

3. 첫 화면 광고 슬롯에 context 적용하기​

주의

기본 권장 구성이 아닙니다. 첫 화면 광고 슬롯에 context를 전달하면 첫 화면 광고가 분석을 기다리는 만큼 늦게 요청됩니다. 첫 화면 광고 슬롯에도 context가 꼭 필요한 경우에만 적용해주세요.

3-1. defer로 로드하는 경우​

  • DOMContentLoaded에서 recommend() 응답을 받은 뒤 첫 화면 광고 슬롯을 요청합니다. recommend()는 maxMs 안에 항상 응답하므로 바깥 타이머는 필요하지 않습니다.

  • maxMs가 첫 화면 광고가 기다리는 최대 시간입니다.

    • 짧게 지정하면(예: 300) 첫 화면 광고의 지연을 최소화합니다. 재방문 시에는 키워드 번들이 브라우저 캐시에 있어 이 시간 안에 context가 포함되지만, 첫 방문 시에는 키워드 번들(br 약 655KB)을 내려받아야 하므로 대부분 context 없이 요청됩니다.
    • 첫 방문에도 context를 포함하려면 1500~3000ms를 권장합니다. 대신 첫 화면 광고는 그만큼 늦게 요청될 수 있습니다.
    <script defer src="https://sdk.naverads.net/libs/ctx-check/ctx-sdk.js" data-root="#postViewArea"></script>

    <div id="ad-top"></div>
    <script>
    document.addEventListener('DOMContentLoaded', function () {
    var analysis = window.gladsdk.CtxCheck
    ? window.gladsdk.CtxCheck.recommend({ maxMs: 300 }).catch(function () { return null; })
    : Promise.resolve(null);

    analysis.then(function (res) {
    window.gladsdk.cmd.push(function () {
    var adSlotInfo = { adUnitId: 'TOP_UNIT_ID', adSlotElementId: 'ad-top' };
    if (res && res.context) {
    adSlotInfo.context = res.context;
    }
    window.gladsdk.defineAdSlot(adSlotInfo);
    window.gladsdk.displayAd('ad-top');
    });
    });
    });
    </script>

3-2. async로만 로드할 수 있는 경우​

  • document.write나 태그 매니저 등으로 defer를 사용할 수 없는 경우의 구성입니다. 아래 세 가지로 첫 화면 광고의 지연을 줄입니다.
    1. 키워드 번들 미리 받기: gladsdkCtxCheck.q.push(['load'])를 추가하면 ctx-sdk.js가 실행되는 즉시 번들 다운로드를 시작합니다. 이후 호출하는 recommend()는 진행 중인 다운로드를 이어서 사용합니다.
    2. 본문 바로 뒤에서 분석 시작: DOMContentLoaded를 기다리지 않고 본문 직후에 분석을 시작합니다. DOMContentLoaded 리스너는 본문 직후 호출이 없는 페이지를 위한 방어 코드입니다.
    3. 바깥 타이머 > maxMs: 바깥 타이머 2000ms, maxMs: 1500으로 첫 화면 광고의 최대 지연을 약 2초로 제한합니다. 바깥 타이머는 스크립트가 로드되지 않을 때 광고 누락을 막으므로 생략하지 않습니다. 자세한 내용은 7. 로딩 방식별 주의 사항을 참고해주세요.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>컨텍스추얼 타겟팅 예제 - async 로드 + 첫 화면 광고 슬롯</title>
<script>
window.gladsdk = window.gladsdk || { cmd: [] };
// 선행 설정과 큐는 gladsdkCtxCheck에 지정합니다.
window.gladsdkCtxCheck = window.gladsdkCtxCheck || { q: [] };
window.gladsdkCtxCheck.config = { root: '#postViewArea' };
window.gladsdkCtxCheck.q.push(['load']); // 1) 키워드 번들 미리 받기
</script>
<script async src="https://sdk.naverads.net/libs/glad/prod/gfp-core.js"></script>
<script async src="https://sdk.naverads.net/libs/ctx-check/ctx-sdk.js"></script>
</head>

<body>
<div id="ad-top"></div>
<script>
(function () {
var TOP_UNIT_ID = 'TOP_UNIT_ID';
var done = false;
var started = false;
var timer = null;

function requestTopAd(res) {
window.gladsdk.cmd.push(function () {
var adSlotInfo = { adUnitId: TOP_UNIT_ID, adSlotElementId: 'ad-top' };
if (res && res.context) {
adSlotInfo.context = res.context;
}
window.gladsdk.defineAdSlot(adSlotInfo);
window.gladsdk.displayAd('ad-top');
});
}

// 분석 결과와 바깥 타이머 중 먼저 온 쪽으로 한 번만 광고를 요청합니다.
function finish(res) {
if (done) return;
done = true;
clearTimeout(timer);
requestTopAd(res && !res.error ? res : null);
}

function startAnalysis() {
if (started) return; // 본문 직후 호출과 DOMContentLoaded 중 먼저 온 쪽만 실행
started = true;
// 3) 바깥 타이머 2000ms > maxMs 1500ms
timer = setTimeout(function () { finish(null); }, 2000);
window.gladsdkCtxCheck.q.push(['recommend', { idle: true, maxMs: 1500 }, finish]);
}
window.ctxStartAnalysis = startAnalysis;

// 방어 코드: 본문 직후 호출이 없는 페이지는 DOMContentLoaded에서 시작합니다.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startAnalysis);
} else {
startAnalysis();
}
})();
</script>

<article id="postViewArea">…본문…</article>
<!-- 2) 본문 바로 뒤에서 분석 시작 -->
<script>window.ctxStartAnalysis();</script>

<div>…댓글 등 본문 아래 영역…</div>
</body>
</html>