How to integrate Ezoic on a NextJS websiteFrancesco Chiaramonte photoby Francesco Chiaramonte

How to integrate Ezoic on a NextJS website

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.

File Structure

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.

Typescript Interface Declaration (ezoic.d.ts)

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.

Loading the Ezoic Script

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:


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.

Placing the Script (using NextJS' Script tag)

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.

Positioning the placeholders

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.

Conclusion

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!