Guide

Astro

Astro Integration

Islands architecture with zero JavaScript

đź’ˇ Astro's Islands Architecture

Static/SSR (Default): Add ?ssr=1 to iframe URLs for accurate view tracking during build/SSR. Views are counted when the page loads in browsers.

Client Island: Use client:* directives for dynamic loading. No special params needed for client-only rendering.

⚠️ Use ?ssr=1 for static/SSR to prevent build-time view inflation!

1 Astro Component (Recommended)

Zero JavaScript, renders to pure HTML.

---
// src/components/BeaverAd.astro
---

<div class="beaver-ad-container">
  <iframe
    src="https://example.com/ad-slot?ssr=1"
    width="280"
    height="90"
    style="border:none;overflow:hidden;"
    frameborder="0"
    scrolling="no"
    loading="lazy"
  ></iframe>
</div>

SSR Mode: The ?ssr=1 ensures views are tracked client-side, not during build. Critical for accurate analytics with static generation!

✨ This sends zero JavaScript to the browser—just pure HTML!

2 Direct HTML in Pages

Just paste the embed code directly into your Astro page.

---
// src/pages/blog/[slug].astro
import Layout from '../../layouts/Layout.astro';
// ... fetch blog post
---

<Layout title={post.title}>
  <article>
    <h1>{post.title}</h1>
    <div set:html={post.content} />
    
    <!-- Ad after content -->
    <div class="my-8">
      <iframe src="https://example.com/ad-slot-id" style="width:100%;height:auto;min-height:90px;border:none;overflow:hidden;" frameborder="0" scrolling="no"></iframe>
    </div>
  </article>
</Layout>

3 Client-Side Lazy Loading

Load ads only when visible (with JavaScript for below-the-fold content).

---
// src/components/BeaverAdLazy.astro
---

<div class="beaver-ad-lazy" data-src="https://example.com/ad-slot">
  <div class="ad-placeholder animate-pulse bg-stone-200 rounded" 
       style="width:280px;height:90px;">
  </div>
</div>

<script>
  const adContainers = document.querySelectorAll('.beaver-ad-lazy');
  
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const container = entry.target as HTMLElement;
        const src = container.dataset.src;
        
        if (src) {
          container.innerHTML = `<iframe src="${src}" width="280" height="90" style="border:none;overflow:hidden;" frameborder="0" scrolling="no"></iframe>`;
        }
        
        observer.unobserve(container);
      }
    });
  }, { rootMargin: '100px' });
  
  adContainers.forEach(el => observer.observe(el));
</script>
Guides