refactor(ads): improve Ezoic ad rendering logic
This commit is contained in:
@@ -10,17 +10,13 @@ interface EzoicPlaceholderProps {
|
||||
|
||||
export function EzoicPlaceholder({ id }: EzoicPlaceholderProps) {
|
||||
const t = useTranslations("common");
|
||||
const [isRendered, setIsRendered] = useState(false);
|
||||
const [hasAdContent, setHasAdContent] = useState(true);
|
||||
const placeholderRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Render the placeholder div first, then tell Ezoic to fill it.
|
||||
// This ensures the DOM element exists before showAds is called.
|
||||
setIsRendered(true);
|
||||
|
||||
// Use requestAnimationFrame to guarantee the placeholder div
|
||||
// is in the DOM before Ezoic tries to find it.
|
||||
// The placeholder div is always in the DOM (including SSR).
|
||||
// Use requestAnimationFrame to ensure the DOM is fully committed
|
||||
// before telling Ezoic to fill it.
|
||||
const rafId = requestAnimationFrame(() => {
|
||||
runEzoic(() => {
|
||||
window.ezstandalone?.showAds(id);
|
||||
@@ -74,7 +70,7 @@ export function EzoicPlaceholder({ id }: EzoicPlaceholderProps) {
|
||||
</span>
|
||||
</div>
|
||||
<div className="ezoic-ad-content overflow-hidden flex items-center justify-center">
|
||||
{isRendered && <div id={`ezoic-pub-ad-placeholder-${id}`} ref={placeholderRef} />}
|
||||
<div id={`ezoic-pub-ad-placeholder-${id}`} ref={placeholderRef} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -20,14 +20,19 @@ export function EzoicAds() {
|
||||
const pathname = usePathname();
|
||||
const isFirstRender = useRef(true);
|
||||
|
||||
// Re-trigger ads on SPA route changes
|
||||
// Per Ezoic docs: destroyPlaceholders first, then showAds in next frame.
|
||||
// Skip the first render to avoid racing with individual EzoicPlaceholder
|
||||
// components that call showAds(id) on mount.
|
||||
// Re-trigger ads on route changes.
|
||||
// First render: call global showAds() as a safety net (placeholder divs are in SSR HTML).
|
||||
// Subsequent renders (SPA navigation): destroyPlaceholders first, then showAds.
|
||||
useEffect(() => {
|
||||
if (isFirstRender.current) {
|
||||
isFirstRender.current = false;
|
||||
return;
|
||||
// On initial page load, give placeholders time to mount, then trigger global showAds
|
||||
const timeoutId = setTimeout(() => {
|
||||
runEzoic(() => {
|
||||
window.ezstandalone?.showAds();
|
||||
});
|
||||
}, 500);
|
||||
return () => clearTimeout(timeoutId);
|
||||
}
|
||||
runEzoic(() => {
|
||||
window.ezstandalone?.destroyPlaceholders();
|
||||
|
||||
Reference in New Issue
Block a user