fix(web): use /r2/replays/ URL for all replay links

Replace /replays/{id}.json.gz with /r2/replays/{id}.json.gz in all pages
(home, matches, bot-profile, playlists, feedback). The /replays/ path is not
served by Cloudflare Pages — it falls back to the SPA shell causing
"Unexpected token '<', <!DOCTYPE..." JSON parse errors. The R2 proxy at
/r2/ is the correct path for replay content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-04-30 13:12:11 -04:00
parent 273736a3f2
commit 27bf570420
5 changed files with 5 additions and 5 deletions

View file

@ -188,7 +188,7 @@ function renderMatchItem(match: BotProfile['recent_matches'][number]): string {
<span class="match-opponent">${opponent ? escapeHtml(opponent.name) : 'Unknown'}</span>
<span class="match-score">${match.participants.map(p => p.score).join(' - ')}</span>
${enrichedBadge}
<a href="#/watch/replay?url=/replays/${match.id}.json.gz" class="btn small">Watch</a>
<a href="#/watch/replay?url=/r2/replays/${match.id}.json.gz" class="btn small">Watch</a>
</div>
`;
}

View file

@ -401,7 +401,7 @@ function initFeedback(): void {
// ─── Utilities ────────────────────────────────────────────────────────────────
function replayUrlForMatch(m: MatchSummary): string {
return `/replays/${m.id}.json.gz`;
return `/r2/replays/${m.id}.json.gz`;
}
function formatDate(s: string | null): string {

View file

@ -147,7 +147,7 @@ export async function renderHomePage(): Promise<void> {
? `${featuredReplay!.participants.map((p) => `<strong>${esc(p.name)}</strong>`).join(' vs ')}${featuredReplay!.winner_id ? ` — Winner: <strong>${esc(featuredReplay!.participants.find((p) => p.bot_id === featuredReplay!.winner_id)?.name || 'Unknown')}</strong>` : ''}`
: 'Demo Replay — Watch a sample battle';
const replayLink = hasLiveReplay
? `#/watch/replay?url=/replays/${featuredReplay!.id}.json.gz`
? `#/watch/replay?url=/r2/replays/${featuredReplay!.id}.json.gz`
: '#/watch/replays';
// Build lazy-loaded content for below-the-fold sections

View file

@ -319,7 +319,7 @@ function renderMatchCard(match: MatchSummary): string {
<span class="match-reason">${match.end_reason ?? '-'}</span>
${match.map_id ? `<span class="match-map">Map: ${escapeHtml(match.map_id)}</span>` : ''}
</div>
<a href="#/watch/replay?url=/replays/${match.id}.json.gz" class="btn small">Watch Replay</a>
<a href="#/watch/replay?url=/r2/replays/${match.id}.json.gz" class="btn small">Watch Replay</a>
</div>
</div>
`;

View file

@ -532,7 +532,7 @@ function addMatchShowMore(container: HTMLElement, remaining: PlaylistMatch[]): v
}
function watchMatch(matchId: string): void {
window.location.hash = `/watch/replay?url=/replays/${matchId}.json.gz`;
window.location.hash = `/watch/replay?url=/r2/replays/${matchId}.json.gz`;
}
function copyEmbedCode(matchId: string): void {