AstroのサイトでGoogle Adsenseを遅延読み込みする
初稿:
- 3 min read -

記事概要
- 先日のBloggerからAstroへ移行した記事の別途詳細
※参考 - Blog移行記事
10年以上の期間お世話になったGoogle Bloggerに別れを告げ、この度AstroでBlogサイトを構築し移行した。Astroは静的サイトを手軽に開発できる軽量フレームワーク。無料のテンプレートをベースにカスタマイズを行った。それなりの作業ボリュームとなったので、詳細は別記事に分け、今回は移行作業全体をまとめる。
目的
- Astroで構築したWebサイトにGoogle Adsenseの遅延読み込みを実装する
- 前回、GoogleアナリティクスをPartytownで遅延読み込みする実装を行ったがAdsenseには適用できなかった
- 例としてディスプレイ広告(バナー)を扱う
- JavaScriptのobserverを使用し、広告が描画エリアに入るタイミングでAdsenseのJSをロードする
用語説明
Astro とは?
Astroは、ブログやマーケティング、eコマースなど、コンテンツ駆動のウェブサイトを作成するためのウェブフレームワークです。Astroは、新しいフロントエンドアーキテクチャを開拓し、他のフレームワークと比較してJavaScriptのオーバーヘッドと複雑さを低減することで知られています。高速でSEOに優れたウェブサイトが必要なら、Astroが最適です。 — Astro公式Docs より引用をDeepLで翻訳
作業環境
- OS - Ubuntu-22.04LTS on WSL2
- Node.js - v20.14.0
- pnpm - v9.4.0
- Astro - v4.11.3
作業詳細
- Google Adsenseを表示するcomponentを作成する
- 実装のポイントは以下
- isProdでデバッグ時にAdsenseのテストモードをオンにする(デバッグ時の不要なリクエスト防止)
- init関数でobserverを定義し、ads-containerが描画エリアに入ったらheadにスクリプトタグを追加する
- スクリプトタグの is:inline data-astro-rerun は、AstroのViewTransitions使用時にページ遷移先でも処理を走らせるために設定
---
const isProd = import.meta.env.PROD
const adsClientId = 'ca-pub-0000000000000000'
const adsBannerId = '0000000000'
---
<div class='ads-container'>
<p>広告</p>
<div>
<ins class="adsbygoogle" style="display:block" data-ad-client={adsClientId} data-ad-slot={adsBannerId} data-ad-format="auto" data-full-width-responsive="true" />
{
isProd ? (
<script is:inline data-astro-rerun>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
) : (
<script is:inline data-astro-rerun>
window.adsbygoogle = window.adsbygoogle || [];
const adBreak = adConfig = function(o) {
adsbygoogle.push(o);
}
</script>
)
}
</div>
</div>
<script is:inline data-astro-rerun define:vars={{ adsClientId, isProd }}>
function init() {
const adElement = document.querySelector('.ads-container');
const observer = new IntersectionObserver(function (entries) {
if (entries[0].isIntersecting) {
let ad = document.createElement('script');
ad.type = 'text/javascript';
ad.async = true;
ad.src =
'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=' + adsClientId;
ad.crossOrigin = 'anonymous';
if (!isProd) {
ad.dataset.adbreakTest='on';
}
document.head.appendChild(ad);
observer.disconnect();
}
})
if (adElement) {
observer.observe(adElement);
}
}
init();
</script>
- […slug].astroにcomponentを設置する
---
import { type CollectionEntry, getCollection } from 'astro:content'
import BlogPost from '../../layouts/BlogPost.astro'
import GoogleAdsense from '@/components/widgets/GoogleAdsense'
export async function getStaticPaths() {
const posts = await getCollection('blog')
return posts.map((post: any) => ({
params: { slug: post.slug },
props: post
}))
}
type Props = CollectionEntry<'blog'>
const post = Astro.props
const { Content } = await post.render()
---
<BlogPost {...post.data}>
<Content />
<GoogleAdsense />
</BlogPost>
以上