create tiny ad network in nextjs

Build Your Own Tiny Ad Network in Next.js

So, you’ve launched a website and started getting some traffic. Exciting, right?

But here’s the catch:

Your visitors are not from high-paying B2B regions. Most of your audience comes from underdeveloped or non-premium ad markets like South Asia or Africa. You’ve applied to ad networks, but they pay pennies, or nothing at all.

I’ve been there too.

I had a site that received 200+ ad clicks in a month or so... and I made just a few dollars. 💔

low ad revenue

So I asked myself:

"What if I build my own mini ad system, and use it to show affiliate links or promote my own products?"

That’s exactly what I did. I created a simple, lightweight, and customizable ad script using Next.js, no need for any third-party platforms.

Let me show you how you can do it too.

Step 1: Create Your Ad Script

Go to the root of your Next.js project and create the following file:

public/scripts/ads.js

Paste this code inside

const ADS = [
{
logo: 'BrandOne',
title: 'Amazing Product for Everyone',
description:
'This is a fantastic product that solves everyday problems in a simple and efficient way. Try it and see the difference.',
cta: 'Explore Now',
link: 'https://example.com/product-one',
},
{
logo: 'BrandTwo',
title: 'Boost Your Workflow Instantly',
description:
'Save hours every week with our productivity tool. Automate tasks and stay focused on what really matters.',
cta: 'Start Free Trial',
link: 'https://example.com/product-two',
},
{
logo: 'BrandThree',
title: 'Get Smarter with Daily Insights',
description:
'Receive fresh insights and tips every day to improve your skills and stay ahead in your field.',
cta: 'Subscribe Now',
link: 'https://example.com/product-three',
},
]
if (typeof window !== 'undefined' && !sessionStorage.getItem('tinyadz_shown')) {
if (!document.getElementById('poppins-font')) {
const link = document.createElement('link')
link.id = 'poppins-font'
link.rel = 'stylesheet'
link.href = 'https://fonts.googleapis.com/css2?family=Poppins&display=swap'
document.head.appendChild(link)
}
sessionStorage.setItem('tinyadz_shown', 'true')
setTimeout(() => {
const ad = ADS[Math.floor(Math.random() * ADS.length)]
const adHTML = `
<style>
.tinyadz-title {
font-family: 'Poppins', sans-serif;
color: #313131;
font-size: 18px;
font-weight: bold;
margin-bottom: 0.5rem;
}
.tinyadz-subtitle {
font-family: 'Poppins', sans-serif;
color: #555;
font-size: 1rem;
line-height: 1.5;
}
.tinyadz-logo {
font-family: 'Poppins', sans-serif;
font-size: 11px;
font-weight: 600;
color: #A855F7;
margin-top: 0.5rem;
text-transform: uppercase;
}
.tinyadz-backdrop {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.tinyadz-box {
font-family: 'Quicksand', sans-serif;
background: #fff;
max-width: 320px;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
position: relative;
}
.tinyadz-close {
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
font-size: 1.2rem;
}
.tinyadz-btn {
font-family: 'Poppins', sans-serif;
width: 100%;
background: #A855F7;
color: #fff;
padding: 0.5rem 1rem;
margin-top: 2rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
<div class="tinyadz-backdrop" id="tinyadz-backdrop">
<div class="tinyadz-box">
<div class="tinyadz-close" id="tinyadz-close">✕</div>
<div style="font-size: 12px; color: gray;">Ad</div>
<div class="tinyadz-logo">${ad.logo}</div>
<div class="tinyadz-title">${ad.title}</div>
<div class="tinyadz-subtitle">${ad.description}</div>
<a href="${ad.link}" class="tinyadz-btn" target="_blank">
${ad.cta}
</a>
</div>
</div>
`
document.body.insertAdjacentHTML('beforeend', adHTML)
document.getElementById('tinyadz-close').onclick = () => {
document.getElementById('tinyadz-backdrop')?.remove()
}
document.getElementById('tinyadz-backdrop').onclick = (e) => {
if (e.target.id === 'tinyadz-backdrop') e.target.remove()
}
}, 3000) // show ad after 3 seconds
}

How Does the code Work?

  • A random ad is picked from the ADS array.
  • The ad is displayed once per session, with a 3-second delay.
  • If the user closes it, it won’t show again until a new session starts.
  • You can easily customize fonts, colors, and delay time.

How we are getting access to public script in layout?

You may think how did we get access to public folder data?

The public/ folder in Next.js is used to serve static files.

When we put the script in public/scripts/ads.js, it becomes accessible directly via the URL /scripts/ads.js.

That’s why we can include it using the <Script> tag without importing it like other modules.

Step 2: Load the Script in layout.tsx

To make this ad show up across your entire site, include the script in your root layout.

Here’s how your app/layout.tsx might look:

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body>
{/* Your analytics or layout components */}
{children}
</body>
{/* TinyAdz Script */}
<Script src="/scripts/ads.js" strategy="afterInteractive" type="module" async />
</html>
)
}

Step 3: Update tsconfig.json

Most of the time it updates automatically, if not then you need to add this path public/scripts/ads.js in tsconfig.json file manually.

In some setups, TypeScript might complain about the ads.js file.

Here is the example of updated tsconfig.json:

"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
"public/scripts/ads.js" // newly added path/file
]

Script in Action

After implementing the script and setup, your site will display a clean, elegant popup ad like this:

nextjs custom ad script UI

If you're running a blog or tool and struggling to make decent ad revenue, this tiny ad script can be a great start. You control the ads, track performance, and even promote affiliate links.

No need for bulky ad networks or middlemen. Just clean, simple monetization that works, even for low-traffic sites.

If you found this article helpful, share it with someone trying to monetize their next.js side project!

Want more tools like this?

Connect me on LinkedIn for more dev tips and resources.

Read Next

Codevertiser Magazine

Subscribe for a regular dose of coding challenges and insightful articles, delivered straight to your inbox