Recently, I have been trying to integrate Ezoic, the Ad platform, on one of my websites (calcolatoriplus.com) in order to have a small revenue coming from it to substain the server costs.
In practice however, integrating Ezoic with a NextJS website is not as easy as integrating it on a normal Wordpress website, for example. With this guide, in a few easy steps, you will easily be able to add Ezoic on your website, without having to do any major changes to your website layout.
You won't need to implement any changes to your existing NextJS website structure, these are the files you will need:
├── public
├── src
│ ├── app
│ │ ├── ezoic.d.ts
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ ├── page.tsx
├── tailwind.config.js
└── tsconfig.json
You will probably already have all these files, except for the ezoic.d.ts
which you have to create. Structure wise, that's pretty much everything you need to add, we will only working with existing and basic NextJS files.
To avoid running into errors on the next step, you need to create the ezoic.d.ts
we mentioned before and put the following snippet inside it:
interface Window {
ezstandalone: any;
}
The provided code is a TypeScript interface declaration that extends the global Window interface.
It adds a new property named ezstandalone
of type any
to the Window
interface. This allows TypeScript to recognize window.ezstandalone
as a valid property.
However, this code doesn't actually add the property to the window object itself; it just informs TypeScript about its existence.
In your layout file, you will want to add the following snippet:
useEffect(() => {
const handleEzoicLoad = () => {
try {
const ezoic = window.ezstandalone;
if (ezoic) {
ezoic.define(103, 104, 105, 106);
if (!ezoic.enabled) {
ezoic.enable();
ezoic.display();
ezoic.refresh();
}
} else {
// Ezoic script is not loaded yet, try again later
setTimeout(handleEzoicLoad, 500);
}
} catch (ex) {
console.error("Error with Ezoic:", ex);
}
};
handleEzoicLoad();
}, []);
This code is using the useEffect React Hook to interact with Ezoic's third-party script. Here's what it does in a nutshell:
It defines a function handleEzoicLoad
that tries to find the Ezoic script
(stored in window.ezstandalone
).
If the Ezoic script is found, it calls some methods on it: define
, enable
, display
, and refresh
.
If the Ezoic script is not found, it sets a timeout to try again after 500 milliseconds.
The handleEzoicLoad
function is called immediately after being defined.
The entire code block is wrapped in useEffect
with an empty dependency array []
, which makes it run only once when the component mounts.
In essence, this code is trying to initialize and interact with the Ezoic third-party script when the component mounts, and it keeps trying until the script is loaded.
The only things you need to change from the code snippet above is the numbers that are defined inside the ezoic.define()
function with the numbers from your own placeholders.
If you do not know how to create placeholders, follow this official guide from Ezoic.
You also need to put in your layout.tsx
file the following code:
<Script
src="https://ezojs.com/ezoic/sa.min.js"
async={true}
strategy="beforeInteractive"
crossOrigin="anonymous"
/>
This is required in order to make sure that the Ezoic script loads as soon as possible, when the page loads.
Once you have created your placeholders on the Ezoic platform, positioning them is extremely easy.
I put the following placeholder in the layout.tsx
file because I want them to appear on every page of my website but if you want them only on specific pages you can simply put it the page.tsx
file for that route, completely up to you!
After having decided where you want your placeholders, put the following snippet
<div id="ezoic-pub-ad-placeholder-106"> </div>
in the file you want, just change the number at the end (in this case it's 106) with the number that the Ezoic dashboard gives you.
That's it! It was easy right? I ran into this issue myself and could not find anything useful online so I ended up solving it on my own and thought that probably someone else has had this issue.
If you have any questions, feel free to DM me on Twitter (or X, call it however you prefer!), I will be happy to answer!