Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

백엔드 개발 블로그

React Hook을 이용하여 카카오 애드핏(Adfit) 연동하기 본문

React

React Hook을 이용하여 카카오 애드핏(Adfit) 연동하기

베꺼 2022. 4. 17. 18:10

React 17 버전을 기준으로 작성된 글입니다. (2022/04)

TL;DR

// KakaoAdfit.jsx
import {useEffect, useRef} from "react";

function KakaoAdFit({unit, width, height, disabled}: any) {
    const scriptElementWrapper = useRef(null);

    useEffect(() => {
        if (!disabled) {
            const script = document.createElement("script");
            script.setAttribute("src", "https://t1.daumcdn.net/kas/static/ba.min.js");
            scriptElementWrapper.current.appendChild(script);

            return () => {
                const globalAdfit = window.adfit;
                if (globalAdfit) globalAdfit.destroy(unit);
            }
        }
    }, [])

    return <div ref={scriptElementWrapper}>
        <ins className="kakao_ad_area" style={{display: "none"}}
             data-ad-unit={unit}
             data-ad-width={width}
             data-ad-height={height}></ins>
    </div>
}

export default KakaoAdFit;
// 사용 예
<KakaoAdFit unit={"DAN-MyExampleAdUnit"} width={"320"} height={"100"} disabled={false}/>

Try #1 : Naive HTML

카카오 애드핏에서 광고 단위를 발급 받으면, 가이드에서는 다음과 같은 형태의 HTML을 원하는 광고 위치에 삽입하도록 안내하고 있습니다.

<ins class="kakao_ad_area" style="display:none;"
 data-ad-unit    = "DAN-MyExampleAdUnit" 
 data-ad-width   = "320" 
 data-ad-height  = "100"></ins> 
<script type="text/javascript" src="//t1.daumcdn.net/kas/static/ba.min.js" async></script>

적당히 wrapping만 해주면 되지 않을까? 생각해서 아래와 같이 컴포넌트를 만들어 봅니다.

function KakaoAdFit({unit, width, height}: any) {
    return <>
        <ins className="kakao_ad_area" style={{display: "none"}}
             data-ad-unit={unit}
             data-ad-width={width}
             data-ad-height={height}></ins>
        <script type="text/javascript" src="//t1.daumcdn.net/kas/static/ba.min.js" async></script>
    </>
}

export default KakaoAdFit;

잘 작동했다면 이 글을 쓸 필요가 없었겠죠???
어느정도 예상했지만 광고가 노출되지 않습니다.

Try #2: createElement를 사용한 스크립트 동적 생성

JSX 문법에서는 script 태그를 사용할 수 없기 때문에, 위와 같이 script 태그를 추가하여도 HTML에 반영이 되지 않습니다.
HTML로 선언하는 것이 아닌, 동적으로 스크립트를 생성하는 방법으로 우회해봅시다.

Ref를 사용하면 low-level HTML element에 접근할 수 있습니다.
컴포넌트가 mount 된 후 최초 한 번 동적 script element를 생성하여, 감싸고 있는 div에 추가해봅시다.

// KakaoAdfit.jsx
import {useEffect, useRef} from "react";

function KakaoAdFit({unit, width, height}: any) {
    const scriptElementWrapper = useRef(null);

    useEffect(() => {
        const script = document.createElement("script");
        script.setAttribute("src", "https://t1.daumcdn.net/kas/static/ba.min.js");
        scriptElementWrapper.current.appendChild(script);
    }, [])

    return <div ref={scriptElementWrapper}>
        <ins className="kakao_ad_area" style={{display: "none"}}
             data-ad-unit={unit}
             data-ad-width={width}
             data-ad-height={height}></ins>
    </div>
}

export default KakaoAdFit;

결과는... 잘 나오는 것 같은데요.

문제는 광고가 없는 다른 페이지로 갔다가 다시 원래의 페이지로 돌아오면 광고가 표시되지 않습니다.

참고: 위와 같이 동적으로 script를 생성할 때, async attribute는 필요 없는 것으로 보입니다.
Stack Overflow: Add defer or async attribute to dynamically generated script tags via JavaScript

Try #3: destroy 구현

이미 한번 로딩이 된 광고 단위에 대해 스크립트를 다시 로딩한다고 하더라도 광고가 다시 갱신되지 않는 것이 원인으로 보입니다.
리액트에서 페이지가 이동되어도 애드핏에서는 인지할 수 없으니까요.
기존에 노출되었던 광고 단위를 삭제하거나 정리하는 기능이 있으면 좋을텐데요...

애드핏 스크립트를 로딩하면 global에 adfit이라는 인스턴스가 생성됩니다.
디버거를 확인하면 해당 인스턴스에 destroy 메소드가 존재하는 것을 확인할 수 있습니다.

해당 destroy 함수를 호출해서 컴포넌트가 unmount될 때 기존 광고 단위를 정리해주도록 합시다.

// KakaoAdfit.jsx
import {useEffect, useRef} from "react";

function KakaoAdFit({unit, width, height, disabled}: any) {
    const scriptElementWrapper = useRef(null);

    useEffect(() => {
        if (!disabled) {
            const script = document.createElement("script");
            script.setAttribute("src", "https://t1.daumcdn.net/kas/static/ba.min.js");
            scriptElementWrapper.current.appendChild(script);

            return () => {
                const globalAdfit = window.adfit;
                if (globalAdfit) globalAdfit.destroy(unit);
            }
        }
    }, [])

    return <div ref={scriptElementWrapper}>
        <ins className="kakao_ad_area" style={{display: "none"}}
             data-ad-unit={unit}
             data-ad-width={width}
             data-ad-height={height}></ins>
    </div>
}

export default KakaoAdFit;

그러면 이제 페이지를 이동하여도 광고가 잘 갱신되는 걸 확인할 수 있습니다.

'React' 카테고리의 다른 글

React Hook 정리 및 Tips  (0) 2022.04.17
Comments