🥷

クライアントサイドルーティングでの忍者AdMax広告表示問題を解決する方法

2024/08/07に公開

想定読者

ReactのSPAアプリケーションで忍者AdMax広告を配信している方 忍者AdMaxについては参考文献記事に譲ります

課題

クライアントサイドルーティングでページ遷移をしたときに忍者AdMax広告が表示されない

前提

以下のライブラリを使用しています

  • react: 18.3.1
  • react-router-dom: 6.23.0

解決法

広告描画コンポーネントがページ遷移によりアンマウントされるとき、忍者AdMax固有のグローバル変数を初期化すると良さそうです

window.__admax_render__ = window.__admax_tag__ = undefined;
window.admaxads = [];

以下にコンポーネントの実装の全体を記述します ご参考になれば幸いです

import { useEffect, type FC } from 'react';
import { useLocation } from 'react-router-dom';

type AdmaxAdType = {
  admax_id: string;
  type: 'switch' | 'banner';
};

declare global {
  // eslint-disable-next-line no-var
  var admaxads: AdmaxAdType[];
  // eslint-disable-next-line no-var
  var __admax_render__: unknown;
  // eslint-disable-next-line no-var
  var __admax_tag__: unknown;
}

const AdCard: FC<{ adId: string; type: AdmaxAdType['type'] }> = ({
  adId,
  type,
}) => {
  const { pathname } = useLocation();
  useEffect(() => {
    const tag = document.createElement('script');
    tag.src = 'https://adm.shinobi.jp/st/t.js';
    tag.async = true;
    tag.classList.add(adId);
    document.body.appendChild(tag);

    globalThis.admaxads ??= [];
    if (globalThis.admaxads.find((x) => x.admax_id === adId)) {
      return;
    }
    globalThis.admaxads.push({
      admax_id: adId,
      type,
    });

    return () => {
      window.__admax_render__ = window.__admax_tag__ = undefined;
      window.admaxads = [];
      Array.from(document.getElementsByClassName(`${adId}`)).map((x) =>
        x.remove(),
      );
    };
  }, [adId, pathname, type]);

  return (
    <div
      key={pathname}
      className={`${
        type === 'switch' ? 'admax-switch' : 'admax-ads'
      } inline-block ${adId}`}
      data-admax-id={adId}
    ></div>
  );
};

export default AdCard;

参考文献

https://zenn.dev/goshouhiro/articles/react-ninja-admax

Discussion