Open2
Remix+CloudflareでWebサイトを作る 50(scriptタグで広告が表示できない)

【2025-02-19】scriptタグで広告が表示できない
背景
以下のような形式でサイトに広告を表示したい。
publicc/hoge.html
にこのコードを書いて、 http://localhost:5173/hoge.html にアクセスすると正しく表示される。
<script type="text/javascript">
var hoge = {
ad_id: "xxxxxx",
};
</script>
<script type="text/javascript" src="https://example.js"></script>
試したこと(解決できず)
しかしhtmlではなくtsxファイルで表示したい、ということで上記などを参考にしながら以下のようにした。
const cleanup = () => {
const scripts = document.querySelectorAll('script[data-ad="true"]');
for (const script of scripts) {
script.remove();
}
};
export function Ad() {
useEffect(() => {
cleanup();
const inlineScript = document.createElement("script");
inlineScript.innerHTML = `
var hoge = {
ad_id: "xxxxxx",
};
`;
inlineScript.setAttribute("data-ad", "true");
document.body.appendChild(inlineScript);
const externalScript = document.createElement("script");
externalScript.src = "https://example.js";
externalScript.setAttribute("data-ad", "true");
document.body.appendChild(externalScript);
return cleanup();
}, [])
return (
<div style={{ width: "100%", minHeight: "100px" }} />
);
}
これではうまくいかなかった。
解決方法
原因
要は外部JavaScript、今回の場合 https://example.js の影響でうまくいかないっぽい。
そしてこの記事では postscribe というものを使用している。
これはTypeScriptでは利用できないので、 @marshallku/react-postscribe というものを使う。
実装
pnpm add @marshallku/react-postscribe
import PostScribe from "@marshallku/react-postscribe";
import { useEffect, useRef } from "react";
const cleanup = () => {
const scripts = document.querySelectorAll('script[data-ad="true"]');
for (const script of scripts) {
script.remove();
}
};
export function Ad() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!ref.current) return;
cleanup();
const script = document.createElement("script");
script.type = "text/javascript";
script.setAttribute("data-ad", "true");
script.textContent = `
window.hoge = {
ad_id: "xxxxxx",
};
`;
document.body.appendChild(script);
return cleanup();
}, []);
return (
<div ref={ref} style={{ width: "250px", height: "250px" }}>
<PostScribe html={`<script src="https://example.js"></script>`} />
</div>
);
}```
解決までに3日くらいかかってしまった。
AIもフルで使ったけどここまで深いことまではわからず。
JavaScript側が何か特殊なことやってるかも?という頭にはなったけどそこから解決に至るまでが遠かった。
雑に解決方法だけ書いたけど原因もうちょっと深掘って記事にしたい。

書いた