Viewer 配信の落とし穴(Astro routes と public 静的の衝突)
症状
- ローカルdevでは正しく表示されるのに、Cloudflare preview だけ viewer が真っ黒 / UIが別物 / モデルがロードされない
- Console はきれい(error/warn なし)
- Network で
viewerHostBoot.jsやbootstrapViewer.jsが見えない、または別HTMLを掴んでる - UIが「昔の構成」に戻ったように見える(キャッシュ疑い)
原因
apps/site/src/pages/viewer/index.astroが存在すると Astro が/viewer/index.htmlを生成し、apps/site/public/viewer/index.html(静的viewer)と 同じパスを取り合う。- Cloudflare Pages では、リダイレクトや末尾スラッシュ解釈も絡み、環境差として顕在化する。
解決
-
/viewerを Astro routes から排除するapps/site/src/pages/viewer/**を削除(フォルダごとでOK)
-
_redirectsで挙動を明確化/viewer/* 200(静的固定)/viewerと/viewer/のみ/app/viewerに 302(導線用)
-
キャッシュ事故を潰す(preview差分対策)
/viewer/*.jsはCache-Control: no-store(必要範囲だけ)
運用ポリシー
apps/site/public/{viewer,schemas,vendor,3dss,...}は “同期される配布物” なので、 同名パスをapps/site/src/pages/**に作らない。- “UI付きビューア” は
/app/viewer、 “素のviewer(配布物)” は/viewer/index.html?...で分離する。
確認手順(再発時の最短チェック)
- Cloudflare preview で
/viewer/index.html?embed=0&mode=prod&ts=1を直打ち → Network にviewerHostBoot.jsとbootstrapViewer.jsが 200 で出るか /viewerを開く →/app/viewerに 302 されるか- Hard reload しても UI が古い版に戻らないか(no-store が効いているか)