skip to content

Astroに広告をつけるのにつまずいた

14 min read

メモ書き

単なる備忘録と、あたまの整理のために。

忍者Admaxという広告サービスを使って、試しにブログに広告をつけようとしたら、だいぶつまずいて、ほとんど休日一日を費やしてしまった。

忍者Admaxは、アカウント登録して、広告枠を作って、あとはコードをコピーして、自分のソースファイルに貼るだけ。手順がとてもシンプルで、使いやすく、審査は一応あるものの、おそらくかなり緩い。サイトによれば、最短5分、私の場合は1時間弱だったかな。

たぶん、昔からあるサービスで、最近のモダンなフレームワ―クとは噛み合わないこともあるよう。わたしはAstroでこのサイトを作っているが、これら2つの相性が悪く手こずった。

大きな問題点は以下の2つ。

  1. cdnでスクリプトを読む必要がある点
  2. スクリプトに document.write() が使われている点。

cdnとは

わたしは完全に趣味でやっているから、知らないことを永遠に調べながらプログラミングをやっている。cdnというのもここ最近よく目にして、なんとなくこういうものか、とわかってきたところ。

と思って調べると、定義を知ってもよくわからない。cdnはContent Delivery Networkの略で、あえて訳せばコンテンツ輸送ネットワークといった感じか。簡単にいうと、データを一箇所ではなく、コピーを作って分散したいくつもの場所に保管して、リクエストがあるたびに、効率的に転送できるようにしたネットワークという感じ。

客観的定義を聞いても何かよくわかった感じは特にしない。

特にweb系のプログラミングでは、画像とか動画とか、まとまったコードやモジュールとかを、html要素のsrcでこちらに呼び込んで来るときに、「cdnを使って」というんだと思う。例としては以下のような感じ。

<img src="https://hogehoge/images/honya.png" >
<style src="https://hagehage/styles/turupika.css>

個人的には、外部ライブラリのDocsなんかを見ると、インストール方法の選択肢に、「cdnを使って」という文言とともに、

<script src="https://mogomogo/scripts/gerogero.js>

というようなコードが載っているのをよく見る。たいがい、npmでインストールするけど。

忍者Admaxはcdnでスクリプトを読み込む

他の方法があるかは知らないが、基本的に忍者Admaxはcdnを通して、スクリプトを読み込む。まずアカウントを作る。「広告枠」というなぞのものを作れと言われる。広告はスマホ用とPC用、そして大きさが大中小などと、いくつか種類がある。「広告枠」は広告の種類を決め、使用目的などを入力すると、一つユニークなidとともに一つの看板が出来上がるといった感じ。それが終わると、以下のようなコードがコピーできる。

通常バージョン

<script src="https://adm.shinobi.jp/s/xxxx"></script>

非同期バージョン

<div class="admax-ads" data-admax-id="xxxxx" style="display:inline-block;"></div>
<script type="text/javascript">(admaxads = window.admaxads || []).push({admax_id: "xxxx",type: "banner"});</script>
<script type="text/javascript" charset="utf-8" src="https://adm.shinobi.jp/st/t.js" async></script>

一個目の通常バージョンはまさにcdnを使っている。非同期バージョンも最後の行でcdnを使っている。非同期バージョンの方が速いらしい。理由はよくわからない。ただ、通常バージョンのスクリプトの一部が、むき出しになっているっぽいから、一部処理を、クライアント側でさせておくのだろう。

一度目のつまずき。広告出ないじゃん。

何も考えずに、通常バージョンのコードをコピーして、astroコードにベタ張りしてみると、表示されない。まあ、大概あたらしいことをやるとこんなものだから、仕方ない。

とりあえず、コンテナで囲って、背景をつけて、視覚的に確認するが、やはり表示されない。

忍者Admaxのアカウントのダッシュボードを見ると、ステータスが「審査中」となっている。 そこをクリックすると、「サイトでの広告表示が確認できません」といった趣旨のことが書いてある。なるほど、やはりこちらのコードの問題かと考える。asyncつけたり、client:load つけたりしてみるが何も起きない。

あれこれ時間がたつうちに表示された。原因はよくわからない。通常審査中であっても、以下のようなバナーが出るはず。

しかし、それすら出なかったから、自分のせいかと思っていたら、時間が経ったら表示された。たぶん、審査の審査みたいな、更に手前の段階の審査が独自であるのかもしれない。

そして、しばらく経ったら、通常の広告も表示された。

ロードしないと表示されない

サイトを訪問した最初は表示されるのだけれど、そこからページ遷移をすると表示されない。どうやら、AstroのSPA的挙動と、スクリプトのcdnロードの相性が悪いらしい。

Astroは通常では、伝統的なルーティングを行う。つまり、a要素で別のリンクに飛べば、そのつどそのリンクにあるhtmlがサーバーから届いてブラウザに表示される。

しかし、““というコンポーネントを置いたページどうしは、クライアント側でルーティングが処理される。いちいち、サーバーからのフェッチと描画ロードがおこらないので、遷移が滑らかになる。

遷移という観点では、いわゆる「モダンな」ページを実現する上で、とってもいい機能である。しかし、クライアント側で滑らかに遷移が処理されることで、逆にページ遷移でロードが起こらないということに繋がる。

一方で、cdnを使ったスクリプトの読み込みは、ページの読み込みが起こらないと誘起されないようである。

つまり、““を使った滑らかな遷移(View Transitionというらしい)は、cdnローディングと相性が悪い。

data-astro-reload? data-astro-rerun? astro:page-load ?

途中でsvelteコンポーネントへ変更もしてみたりとかなり試行錯誤したけれど、結局astroにもどる。

ViewTransitionをうまく制御すれば、もしかしたら、ページ遷移に伴ってcdnローディングができるかもしれない。astroのDocsを読んで見るとそれっぽいのが3つ。

  • data-astro-reload
  • data-astro-rerun
  • astro:page-load

ここまで生成AIさんの助けを多分にもらっている。1つ目のdata-astro-reloadは、やつの提案。ただ、こやつ間違っとる!“

しかし当然ダメ。Docsを見ると、そもそも、data-astro-reloadは、a要素に使うもの。つまりcdnを読みたいページに、遷移する前のリンクにくっつける。ただ、ページ全部のaにdata-astro-reloadをつけるなんて写経はやりたくないから却下。

data-astro-rerun。ふむふむ、こいつも有望そうな見た目だ。Docsをざっくり見ていたらあった。ViewTransition(滑らか遷移モード)の時にscript要素につけると、通常は実効されないスクリプトが毎回実効されるらしい。

残念こいつもだめだった。外部cdnから読み込んだスクリプトは使えないとのこと。完全にインラインで書いたスクリプトは実効されるが、外部はだめ。死。

astro:page-load。これは、ViewTransitionモードで画面遷移が起こり、遷移が完全に終了したときに、documentが吐き出すイベントのよう。最終的にはこれを使うのがまあいいよう。ここでは割愛するけれど(ただどこかでそれを1テーマに書いたほうがよさそう)、このあともかなり四苦八苦した。astroのフロントマッタ―とscriptで変数を共有する方法なのだけれど、かなりつまずいた。とりあえずそれはまたこんど(memo: define vars vs カスタムコンポーネント)。

忍者Admaxさんdocument.wrire()使ってる問題

かれこれあって、結局astro:page-loadとhtmlのカスタムコンポーネントでいいところまではいけたが、コンソールを見ると謎のエラーが見える。

そして、デプロイ後の画面を見ても、いままでなら初期ロードでは表示されていた広告さえも、表示されたかと思ったら、すぐに消えたりする。なんじゃこりゃ!

どうやら、コンソールを覗くと、document.write()とという関数がcdnスクリプトの中に入っているらしい。そして、document.write()というのは、htmlになんでも書き込めるヨという、お強いメソッドだから、ウイルス挿入のリスクが高い。ということで、基本は初期ロード時しか実効できないようになっているらしい。

頑張って、ViewTransitionイベントを捕まえて、cdnを読んでみたはいいものの、document.write()が実効出来ないせいで、結局広告は表示されない。撃沈。

Aiさんいわく、document.write()は現代ではあまり使われないとのこと。忍者Admaxさん、改善おねがいします!と言っても、モダンフレームワークを使う界隈と、忍者Admaxを使う界隈が一致してなさそうだから、需要もないかもしれん。

最終手段。ViewTransition消滅

ようは、ViewTransitionを切れば、毎回のページ遷移でロードが起きて、広告は表示される。すみません。読者のみなさんにとっては、表示されないほうが嬉しいのはわかっています。すみません。

大胆に切る。

Astrowindというテンプレをつかっているから、そもそも““がどこにあるのかわからん。全ページに適用されているんだから、レイアウト系のコンポーネントだろうと思ったら、あった。英語は弱いからあんまり読みたくないけれど、ちゃんとViewTransitionを切りたいなら、ここをコメントアウトしろというのがあったからコメントアウト。

滑らかな遷移というモダンフレームワークの利点を捨ててしまって、やはりほんの少しだけカクつくのだけど、いうてそこまで気になるもんでもないから。よしとする。

かんれん記事