Serve hashed assets from R2 via CDN_BASE (#3773)

## Description:

Add an optional CDN_BASE env var that prefixes hashed asset URLs from
asset-manifest.json, so the app can serve static assets from R2/CDN
instead of the app origin. The value is determined at runtime via the
EJS template (window.CDN_BASE) — empty string means "same origin,"
matching today's behavior.

A hack to load the worker bundle:

A same-origin Blob script that dynamic-import()s the cross-origin worker
module and buffers early postMessage calls until the imported module's
handler attaches, sidestepping the browser's refusal to construct a
Worker directly from a cross-origin URL.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
Evan
2026-04-27 11:27:54 -06:00
committed by GitHub
parent 4aeece4aef
commit 4aa726cfd8
14 changed files with 295 additions and 23 deletions
+2 -1
View File
@@ -141,8 +141,9 @@ export async function buildPreview(
publicInfo: ExternalGameInfo | null,
): Promise<PreviewMeta> {
const assetManifest = await getRuntimeAssetManifest();
const cdnBase = process.env.CDN_BASE ?? "";
const buildAbsoluteAssetUrl = (path: string) =>
new URL(buildAssetUrl(path, assetManifest), origin).toString();
new URL(buildAssetUrl(path, assetManifest, cdnBase), origin).toString();
const isFinished = !!publicInfo?.info?.end;
const isPrivate = lobby?.gameConfig?.gameType === "Private";