[Astro] Ad Integration (Google AdSense)

2026-03-31 hit count image

Sharing how to integrate Google AdSense ads into an Astro blog. Covers ad component setup, inserting ads within markdown using a custom rehype-in-feed-ads plugin, and more.

astro

Overview

In the previous post Comment System (Utterances), we covered the comment system. In this post, I’ll explain how to integrate Google AdSense ads for blog monetization.

Ad integration is divided into two main parts. The first is placing ads at fixed positions in the post layout (top, bottom, left, right), and the second is inserting ads in the middle of markdown content. For the latter, I developed a custom rehype plugin.

Loading the AdSense Script

The Google AdSense script is loaded in Head.astro. This script must be loaded on every page for ads to display correctly.

<!-- src/components/Head.astro -->
<script
  async
  src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXX"
  crossorigin="anonymous"
></script>

The async attribute is used to prevent blocking page loading.

Ad Components

Individual components are created for each ad placement position. This separation allows each position’s ad to be independently modified or disabled.

src/components/ads/
├── TopAds.astro      # Top of post
├── BottomAds.astro   # Bottom of post
├── LeftAds.astro     # Left side
├── RightAds.astro    # Right side
└── InFeedAds.astro   # Within content (feed)

Each component contains AdSense ad code and is placed at the appropriate position in PostLayout.astro.

<!-- src/layouts/PostLayout.astro -->
<TopAds />

<div class="container container-contents">
  <div class="row">
    <LeftAds />
    <article class="col-lg-8 col-md-10 mx-auto" data-pagefind-body>
      <slot />  <!-- Markdown content -->
      <InFeedAds />
    </article>
    <RightAds />
  </div>

  <BottomAds />
</div>

ads.txt Configuration

To prevent ad fraud, public/ads.txt and public/app-ads.txt files are placed in the project. These files contain verification information provided by Google AdSense and serve to verify that “only this ad network can serve ads on this site.”

When placed in the public/ directory, they are copied as-is to the dist/ directory during build, making them accessible at https://deku.posstree.com/ads.txt.

Custom rehype-in-feed-ads Plugin

Beyond ads fixed in the layout, there are times when you want to insert ads in the middle of markdown content. For this purpose, I developed the rehype-in-feed-ads plugin.

Usage

Simply write a <!-- ad --> comment at the position where you want an ad in the markdown file.

## Section 1

Content...

<!-- ad -->

## Section 2

Content...

During build, <!-- ad --> comments are automatically replaced with AdSense ad blocks.

Plugin Implementation

The plugin recursively traverses the HAST (HTML syntax tree) to find <!-- ad --> comment nodes and replace them with ad HTML.

// src/plugins/rehype-in-feed-ads.mjs
const AD_HTML = `<div class="in-feed-ads ads-container">
  <div class="ads-block ads-left">
    <ins class="adsbygoogle" ... data-ad-slot="2718813593"></ins>
    <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
  </div>
  <div class="ads-block ads-center">
    <ins class="adsbygoogle" ... data-ad-slot="6492035359"></ins>
    <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
  </div>
</div>`;

function replaceInChildren(children) {
  const result = [];
  for (const child of children) {
    if (
      child.type === 'raw' &&
      child.value &&
      child.value.trim() === '<!-- ad -->'
    ) {
      result.push(createAdNode());
    } else if (child.type === 'comment' && child.value.trim() === 'ad') {
      result.push(createAdNode());
    } else {
      if (child.children) {
        child.children = replaceInChildren(child.children);
      }
      result.push(child);
    }
  }
  return result;
}

export default function rehypeInFeedAds() {
  return (tree) => {
    if (!tree.children) return;
    tree.children = replaceInChildren(tree.children);
  };
}

How It Works

Here’s a summary of how the plugin works:

  1. Recursively traverses the HAST tree
  2. When a <!-- ad --> comment node is found, replaces it with AdSense ad HTML
  3. Handles both raw type (string) and comment type (parsed comment)

This approach recreates the pattern of inserting ads with {% include in-feed-ads.html %} in Jekyll. Since you only need to add <!-- ad --> when writing markdown, it’s straightforward.

Conclusion

In this post, we looked at how to integrate Google AdSense ads into an Astro blog.

  • Loading AdSense script in Head.astro
  • Setting up ad components by position (Top, Bottom, Left, Right, InFeed)
  • Preventing ad fraud with ads.txt
  • Automatically converting <!-- ad --> comments in markdown to ads with the custom rehype-in-feed-ads plugin

In the next post Search Implementation with Pagefind, we’ll cover how to implement search functionality on a static site.

Series Guide

This post is part of the Jekyll to Astro migration series.

  1. Why I Migrated from Jekyll to Astro
  2. Astro Installation and Project Setup
  3. Content Collections and Markdown Migration
  4. Multilingual (i18n) Implementation
  5. SEO Implementation
  6. Image Optimization — Custom rehype Plugin
  7. Comment System (Utterances)
  8. Ad Integration (Google AdSense)
  9. Search Implementation with Pagefind
  10. Layout and Component Architecture
  11. GitHub Pages Deployment
  12. Social Share Automation Script
  13. Troubleshooting and Tips

Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!

App promotion

You can use the applications that are created by this blog writer Deku.
Deku created the applications with Flutter.

If you have interested, please try to download them for free.



SHARE
Twitter Facebook RSS