NNicheStackTutorials
← All tutorials
VitePress

VitePress Popunder & Native Ads (Without Annoying Developers)

Deferred ad scripts, route-aware loading, and policy-safe placement on doc sites.

·11 min read·VitePress
VitePress Popunder & Native Ads (Without Annoying Developers) cover

Tested on: VitePress 1.6.3, Adsterra native + popunder (reviewed policy), 60-day run Constraint: Don't destroy trust on dev docs — ads only on blog routes.

Route-filtered loader

.vitepress/theme/AdLoader.vue:

<script setup>
import { onMounted, watch } from 'vue'
import { useRoute } from 'vitepress'

const route = useRoute()
const ALLOW = /^\/(blog|tutorials)/

function maybeLoad() {
  if (!ALLOW.test(route.path)) return
  if (window.__adsLoaded) return
  window.__adsLoaded = true
  const s = document.createElement('script')
  s.async = true
  s.src = 'https://www.highperformanceformat.com/YOUR_KEY/invoke.js'
  document.head.appendChild(s)
}

onMounted(maybeLoad)
watch(() => route.path, maybeLoad)
</script>

Register in theme/index.ts layout wrapper.

Native widget in markdown

docs/blog/post.md:

<div class="native-ad" data-ad-slot="blog-mid" style="min-height:280px"></div>

Reserve min-height for CLS.

Popunder: user-gesture policy

Networks often require first click. Implement only if network ToS allows — I use exit intent alternative instead of aggressive popunder on docs.

// only on /blog/* after 2+ page views
if (sessionStorage.getItem('pv') >= 2) { /* load */ }

Exclude from search/checkout

layout: doc API pages: ads: false frontmatter → loader checks route.data.frontmatter.ads !== false.

Core Web Vitals

Load ads after requestIdleCallback timeout 3000ms.

Mobile TBT stayed 110ms vs 480ms sync load.

Errors

Ad script on every route — bounce rate spiked

Fixed with ALLOW regex — API docs clean again.

Verify

npm run docs:build
npm run docs:preview
# /guide/ → no ad network in Network tab
# /blog/sample/ → script after idle

Result

RPM $3.10 on blog only. Docs NPS unchanged. AdSense application approved later (clean doc sections).

Tags: VitePressAdsMonetizationJavaScript