Hayami Kaito Web
~/tech

静的エクスポートの Next.js サイトに Google AdSense の自動広告を入れる(Cloudflare Pages)

published

静的エクスポート(output: "export")でビルドしている Next.js のサイトに、Google AdSense の自動広告を入れる手順を説明します。このサイト(Next.js 16 + Cloudflare Pages)に実際に入れたときの変更を例にします。

結論として、次の 3 つを用意すれば済みます。サーバー側の処理は要らないので、静的エクスポートのままで使えます。

用意するもの置く場所
広告のスクリプト(adsbygoogle.js)ルートレイアウト src/app/layout.tsx に next/script の <Script> で
サイト審査用の meta タグ同じファイルの metadata の other に
ads.txtpublic/ads.txt

環境

項目バージョン
Next.js16.4.0(App Router・output: "export")
React19.3.0
Node.js24.x
pnpm12.x
ホスティングCloudflare Pages(GitHub 連携で自動デプロイ)

AdSense のアカウントを作り、管理画面でパブリッシャー ID(ca-pub- で始まる番号)を確認しておきます。以下では ca-pub-XXXXXXXXXXXXXXXX と書きます。

HTML の head に直接書けない

AdSense の管理画面には、<head> に貼り付ける次のようなコードが表示されます。

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

ところが App Router の Next.js には、手で編集する HTML ファイルがありません。HTML はビルド時に、レイアウトとページのコンポーネントから作られます。そこで、

  • スクリプトは Next.js の <Script> コンポーネントで読み込む
  • meta タグは metadata に書いて Next.js に出力してもらう

という形に置き換えます。全ページに広告を出すので、どちらもルートレイアウト(src/app/layout.tsx)に書きます。Next.js のドキュメントでも、全ページで使うサードパーティーのスクリプトはルートレイアウトに置く例になっています。

手順

1. パブリッシャー ID を 1 か所にまとめる

ID はスクリプトの URL と meta タグの 2 か所で使うので、サイトの設定をまとめているファイルに定数として置きました。

src/lib/site.ts:

export const siteConfig = {
  name: "Hayami Kaito",
  // ...
  locale: "ja_JP",
  /** Google AdSense のパブリッシャー ID(public/ads.txt の pub- と揃える) */
  adsenseClient: "ca-pub-XXXXXXXXXXXXXXXX",
} as const;

パブリッシャー ID は、公開したページの HTML に必ず載る値なので、秘密情報ではありません。

2. ルートレイアウトにスクリプトと meta タグを足す

src/app/layout.tsx の変更点です。

 import type { Metadata } from "next";
 import { Geist_Mono, Noto_Sans_JP } from "next/font/google";
+import Script from "next/script";
 // ...

 export const metadata: Metadata = {
   // ...
   openGraph: {
     siteName: siteConfig.name,
     locale: siteConfig.locale,
     type: "website",
   },
+  // AdSense のサイト審査用
+  other: { "google-adsense-account": siteConfig.adsenseClient },
 };

 export default function RootLayout({ children }: LayoutProps<"/">) {
   return (
     <html lang="ja" className={/* ... */}>
       <body className="flex min-h-full flex-col font-sans">
         <Header />
         <main className="flex-1">{children}</main>
         <Footer />
       </body>
+      <Script
+        async
+        src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${siteConfig.adsenseClient}`}
+        crossOrigin="anonymous"
+        strategy="afterInteractive"
+      />
     </html>
   );
 }
  • metadata の other に書いたキーと値は、<meta name="キー" content="値"> として <head> に出力されます
  • <Script> の strategy="afterInteractive" は既定値で、ページがある程度読み込まれてからスクリプトを読み込みます。広告はページの表示を待たせる必要がないので、これにしました
  • crossorigin は JSX では crossOrigin と書きます

3. public/ads.txt を置く

public/ に置いたファイルは、ビルド後にサイトのルートにそのまま配信されます。public/ads.txt を作り、次の 1 行を書きます。pub- のあとはご自身の番号に置き換えます(ca- は付けません)。

google.com, pub-XXXXXXXXXXXXXXXX, DIRECT, f08c47fec0942fa0

これで https://<ドメイン>/ads.txt で見えるようになります。

4. ビルドして出力を確かめる

pnpm build

out/index.html を開いて、meta タグと広告のスクリプトが入っているかを確かめます。

grep -o '<meta name="google-adsense-account"[^>]*>' out/index.html
grep -c "adsbygoogle.js" out/index.html
ls out/ads.txt

このサイトでは、<head> に次の 2 つが出力されていました。

<link rel="preload" href="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXXXX" as="script" crossorigin=""/>
<meta name="google-adsense-account" content="ca-pub-XXXXXXXXXXXXXXXX"/>

5. デプロイして AdSense の審査を申請する

GitHub に push すると、Cloudflare Pages が自動でビルドして公開します。

git push origin master

公開されたら https://<ドメイン>/ads.txt がブラウザで開けることを確かめ、AdSense の管理画面でサイトを追加して審査を申請し、自動広告をオンにします。

ハマりどころ

HTML のソースに <script> タグが見当たらない

strategy="afterInteractive" の <Script> は、ビルドした HTML には <script src="...adsbygoogle.js"> としては出てきません。上のとおり <link rel="preload"> で先読みの指示だけが入り、実際の <script> タグはブラウザでページが動き始めてから Next.js が追加します。

「ページのソースを表示」で <script を探しても見つからないのはこのためです。読み込まれているかは、ブラウザの開発者ツールの「Elements」か「Network」タブで確かめます。

Cloudflare Pages の X-Frame-Options: DENY は外さなくてよい

このサイトは public/_headers で X-Frame-Options: DENY を返しています。これは「このサイトをほかのサイトの iframe に入れること」を禁止する設定なので、このサイトの中に広告の iframe を表示することには影響しません。

なお、Content-Security-Policy(CSP)を設定しているサイトでは、AdSense のドメインを許可する必要があります。このサイトは CSP を設定していないので、何も変えていません。

審査が通るまで広告は出ない

コードを入れても、審査が通るまでは広告は表示されません。pnpm dev の手元の環境でもスクリプトは読み込まれますが、広告の表示は確認できません。

まとめ

  • 静的エクスポートの Next.js でも、AdSense の自動広告はクライアント側で読み込むスクリプトなので、そのまま使えます
  • <head> に貼るコードは、ルートレイアウトの <Script> と metadata.other に置き換えます
  • ads.txt は public/ に置けばサイトのルートで配信されます

参考