I have a custom javascript for running ads on my NextJS site. This is provided by the ad provider / ad exchange.
It looks something like this:
<script type="text/javascript" src="//cdn.adsite.com/static/js/ad.js" ></script>
Along with this I have div tags that I place on the web page, for example:
<div id="ad-tag-6098" ></div>
<div id="ad-tag-6099" ></div>
<div id="ad-tag-6076" ></div>
These three div tags are three ad slots on a page and get populated with the ad using the ad.js javascript.
This works fine on a normal load /reload of a page.
However, when I navigate to a page using the internal navigation router, this javascript doesn't get triggered and the ad doesn't display.
What is the correct way to reload the ad.js so that the div tags (ad slots) display the ad correctly, and also refresh correctly even when we navigate through the nextjs router? Can you please help?
UPDATE: This problem is even deeper than I thought. Just reloading of javascript is not enough. Since these are ad slots, when the page transitions / route changes, the used ad slots stay in the memory, so the ad script treats them as already displayed. This causes an error.
The desired behaviour is as follows:
You might know but I wanted to remind you that there are listeners for route changes in NextJS
router.events.on('routeChangeComplete', handleRouteChange)
router.events.off('routeChangeComplete', handleRouteChange)
you can reload the script when the route changes with the help of these events. you can fetch the script and append it at the end of the body script for every route change. so the memory of the adjs will be restarted
I hope this router.events helps, waiting for your feedback.
UPDATE: According to your comment, I wanted to update here. With the help of these router.events you have the control. You can manipulate the DOM. It should not be React specific solution or NextJS specific solution. You have the power of Javascript.
If you are the one adding all the ad divs, you can add an data attribute to select those divs later.
For example, Lets say you have added this ad div
<div id="ad-tag-6098" ></div> // instead of this!
<div id="ad-tag-6098" data-ad="true" ></div> // add this one!
by using routeChangeStart event of router.events, you can select the divs with data-ad attribute and remove the filled content of them from DOM before routeChangeComplete event and when script is reloaded, it should not throw an error.
const adDivs = document.querySelectorAll('[data-ad="true"]'); // you can get these divs and remove the child of them before routeChangeComplete cycle
What do you think about this updated part of my answer, let me know your thoughts.
Another simple trick would be to add unique query string which would cause the script to load and execute again and again.
For removing old ads
Script
component onLoad
event handler can be used.
import Script from 'next/script'
export default function Home() {
const unique_id = new Date().getTime();
return (
<>
<Script
id={unique_id}
src={`//cdn.adsite.com/static/js/ad.js?v=${unique_id}`}
onLoad={() => {
// execute code after script load
}}
/>
</>
)
}
Better approach would be to load script only once and refresh the slots which has been created with refresh functionality provided, or you can clear and load new ads with same functionality.
function refreshAllSlots() {
googletag.cmd.push(function() {
googletag.pubads().refresh();
});
}
function clearAllSlots() {
googletag.cmd.push(function() {
googletag.pubads().clear();
});
}
Note:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With