Vercelにpushしても反映されないのはGit未接続だから|canonicalが古いまま残る
リポジトリを直しても本番が何か月も古いままだった。プロジェクトがGitHubに接続されておらず、過去にCLIから手で流したビルドが配信され続けていた。独自ドメインのcanonicalがvercel.appを指したままになっていた。
開発記録
実際に手を動かして詰まった点と、その解き方を書いた記事をまとめています。
リポジトリを直しても本番が何か月も古いままだった。プロジェクトがGitHubに接続されておらず、過去にCLIから手で流したビルドが配信され続けていた。独自ドメインのcanonicalがvercel.appを指したままになっていた。
サーチコンソールの通知は「検出しました」であって「違反です」ではない。重複の通知に対してnoindexで応じたら、順位が付いていたページのクリックが0になった。直すべき通知と、そのままにしてよい通知を見分ける。
curlの引数に日本語を直接書くと、受け取った側には別の文字列が届く。楽天のAPIで0件が返り、キーワードが効かないと結論づけたが、APIもフォームも正常だった。渡した文字列が届いているかを先に疑う。
WordPressのサイトマップが1本も存在せず、Search Consoleで取得できませんでしたになっていた。原因はテーマが本体のサイトマップを切っていたこと。1つ直すと次が出てくる3段構えだった。
ドメインを移したあと 404.html にJSを入れて転送していたが、HTTPステータスは404のままで、5日間Googleに404を返し続けていた。GitHub Pagesは301を返せないので、全パスぶんの200を返す実体を生成して置いた。
サーチコンソールの発見済みページが33,659件で止まっていた。サイトマップは54,780URLあり、1ファイルの上限50,000を超えていた。索引形式に分けると、どの種類が登録されていないかもGSCで読めるようになる。
記事18本の平均順位は6.4で1ページ目なのに、90日のクリックが2件しかなかった。原因はタイトルの長さで、18本中17本が30字を超え、検索語が表示されない側に入っていた。実際に表示が付いていたクエリの語が、69字タイトルの55字目以降にあった。
レンタルサーバーがGitHub ActionsのランナーIPを弾いていて、デプロイが1か月半届いていなかった。鍵は正しいのに Connection closed になる。SSHできる別サーバーを踏み台にして解決した。
サイトマップに載せたクエリ付きURLが、どれもクエリ無しのURLを正規URLとして申告していた。原因は url()->current() がクエリ文字列を含まないこと。2つのサイトで同じ原因が起きていて、片方は1か月半インデックスされていなかった。
DNSもCAAもDNSSECも正常なのに、GitHub Pagesの証明書が1週間発行されなかった。原因は設定の順序で、Pagesを作ってすぐカスタムドメインを入れていた。デプロイして github.io 側で200を確認してからドメインを設定したら25秒で approved になった。
お名前.comのDNSレコード設定にAレコードを入れても1件も反映されなかった。原因はネームサーバーが取得時の既定値 dns1/dns2.onamae.com のままで、レコード設定が効くのは 01〜04.dnsv.jp を使っているドメインだけだった。144ドメインを一斉に調べたら19件が同じ状態だった。
GitHub Pages の証明書が発行されない。原因を推測で2回報告し、2回とも崩れた。手元のリゾルバのキャッシュを事実として扱ったのが間違いだった。
46ページが発見済み未登録。各ページに2万字あるのに、canonical が自分自身を指していなかった。修正は1か月半前にコミット済みで、本番に届いていなかっただけ。
WordPress に記事を一括投入したあと、片方のサイトだけ画面の先頭に PHP Warning が出た。原因は post_author=0。Cocoon では出ず AFFINGER では出る。3サイト143件を直すまで。
GitHub Pages は301を返せない。404.html に JS を入れて転送したが、HTTPステータスは404のままで、5日間 約7,000URLが行き先を失っていた。200を返す実体ファイルに置き換えるまでの記録。
3つのサイトのフッターに info@ のアドレスを載せていた。削除依頼の窓口として全ページに出していたのに、MXレコードが1本も設定されていなかった。送られたメールはすべてエラーで返っていたことになる。Cloudflare Email Routing で受信できるようにするまでの手順を書く。
毎日13時に走る同期処理が、4日のうち3日失敗していた。ログを見ると dial tcp のタイムアウト。コマンドが失敗したのではなく、TCP接続すら張れていない。接続の待ち時間を延ばし、間隔を空けて3回試すようにした実装を書く。
3つのサービスのAPIから同じ分類のデータを集めることになった。最初はIDをコードに書いていたが、取り違えても誰も気づけない。名前で引き当てる方式に変えたところ、社ごとに呼び方が違うことや、そもそも存在しない分類があることが分かった。
Vite + React で作ったトップページを curl で取得したら、リンクが1つも入っていなかった。div id=root が空で、中身はすべてJavaScriptが描いていた。Googleは実行してくれるが、生成AIのクローラーの多くは実行しない。何が見えていなかったのか、どう直したのかを書く。
静的サイトの投稿機能をSupabaseで作った。行レベルセキュリティ(RLS)は3つの条件を満たすよう慎重に書いた。ところが匿名キーで実際に攻撃してみたら、投稿者が自分の投稿を承認済みにできてしまった。PostgreSQLの関数は既定でPUBLICにEXECUTE権限が付くためだった。
AdSenseの審査に落ちたサイトを整えるなかで、プライバシーポリシーもフッターも無いことに気づいた。テンプレートを貼るのではなく、コードを調べて実際に使っているサービスだけを書いた。必要なページと、それぞれに何を書いたかをまとめる。
AdSenseに登録したまま放置していたサイトを整理するため、ドメインの生死を調べた。whoisでは3件が「登録あり」に見えたが、RDAPで照会し直すと全件が失効していた。TLDごとに応答形式が違うことが原因だった。確実に判定する方法をまとめる。
薄い自動生成ページ340本を noindex にしてサイトマップからも外した。それで対策は終わったつもりだった。しかし記事一覧を開くと、そのページへのリンクが343件並んだままだった。noindex は検索エンジンの索引から外す指定であって、審査員が見るのを止めるものではない。何を勘違いしていたのかを書く。
自動生成した記事340本を抱えた技術ブログが、AdSenseの審査に落ちた。理由は「有用性の低いコンテンツ」。感覚で直すのではなく、全記事の文字数と見出し構成を実測して原因を切り分けた。何が薄かったのか、どこを直したのかを数字で記録する。
週次のデータ更新のたびに、サイトから投票ボタンと口コミ欄が消えていた。原因は、再利用ワークフローを呼ぶときに secrets: inherit を書いていなかったこと。pushでのデプロイでは正常に動くため、手元では再現しない。同じ経路で続けて踏んだ3つの落とし穴と、その直し方をまとめる。
未使用ドメインをCloudflare経由で301転送しようとして、19件が何時間経っても pending のままだった。原因は、Cloudflareが割り当てるネームサーバーの組がドメインごとに違うことだった。レジストリのwhoisで一件ずつ確認して初めて分かった経緯と、確認の手順をまとめる。
「リポジトリにgtagが無い=GA4が動いていない」と思って283リポジトリをgrepしたら、154件が未計測という結果が出た。実際にサイトへアクセスして確かめ直したら、本当に困っていたのは5件だけだった。静的解析が嘘をつく理由と、GA4 Admin APIを使った確実な確認手順をまとめる。
Reactの検索UIで`import data from './data.json'`していたら、データが5207件に増えた瞬間にメインバンドルが4.3MBになった。原因と、63KBまで削った方法の記録。
公開している GitHub リポジトリ179件については、 README とコミット履歴から構成と変更の流れを機械的にまとめた記録を用意しています。 読み物ではないため、この一覧には並べていません。
どんなものを作ってきたかは制作物のページから確認できます。 解説動画は、それぞれの記録のページに置いてあります。