釣りアプリで潮見表ページをビルド時に量産した話(港 SEO)
端末計算と静的 HTML の役割分担。港を増やし、毎日フルビルドはやめた理由。
Angla には、港ごとの潮見表ページがあります。アプリ内では端末側で潮汐を計算しつつ、Web 向けには ビルド時に静的 HTML を出す 形も持っています。港の数は、途中で大きく増やしました(v1 の数十港から、v2 の全国二百港超へ)。
この記事は「なぜ静的ページを量産したか」と、「毎日フル再ビルドはやめたか」の話です。
なぜクライアント計算+静的ページか
潮汐そのものは、アプリ内サービスで計算できます。一方で検索流入や共有 URL を考えると、クローラが読めるページがあった方が楽です。Flutter Web の画面だけだと、インデックスの扱いが弱くなりがちなので、潮見表は静的ページ側も用意しました。
つまり役割分担です。
- アプリ: その場の体験(計算・UI)
- 静的ページ: 港名で見つかる入口
港データの持ち方
港マスタは機械生成のテーブル(v2)を正本寄りにしています。直接手で巨大配列をメンテしない、が先です。v1 から v2 へ切り替えたときは、既存港の座標が一致するか、干満時刻が許容誤差に収まるかをテストで見ました。
表示名だけ気象庁寄りの表記に変わった港もあり、「データは同じでもラベルが変わる」点は運用で意識が必要でした。
ビルド時生成と、毎日フルビルドをやめた話
静的ページはコードデプロイのタイミングで更新する方針に寄せています。以前は毎日フル再ビルドする運用もありましたが、GitHub Actions の枠を食う主因の一つでもあったので、定時のフルビルド cron は廃止しました。
アプリ側は端末計算できるので、「SEO 用 HTML を毎日焼き直す」必要は薄かった、という判断です。日次で重いのはスコア生成の方で、そちらは VPS cron に移しています。
SEO で効いた点 / やりすぎない境界
港名入りのページは、長い尾の検索と相性がよいです。一方で、自動生成テンプレートが並びすぎると、サイト全体が「中身の薄い量産」に見えやすい、という副作用もあります。Angla の Web トップは検索向きというよりアプリ入口なので、収益の主戦場も AdMob(ストアアプリ)側に置いています。
静的ページは入口として有用でも、サイト全体を記事メディアのように見せる必要はない、というのが今の境界です。
まとめ
- 体験はアプリ計算、発見は静的ページ
- 港マスタは生成物として扱い、回帰テストで守る
- 毎日フルビルドは枠を溶かすので、デプロイ時更新に寄せた
- SEO 入口と、アプリ収益の主戦場は分けて考える
全体像は Angla を公開するまで にあります。