From 1f137e92d32081809de611d530e2ad464fddf8bf Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Mon, 7 Sep 2026 11:40:01 -0400 Subject: [PATCH] boot: derive the home origin from the page URL, not location.origin A GitHub Pages project site is served under //, so the kernel's {home-origin}/apps/index.json fetch went to the host root and 404ed. Every other URL the tab and worker resolve is already relative to location.href; the hello now matches. --- runtime/wit/internal.wit | 5 +++-- web/boot.ts | 5 ++++- web/worker.ts | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/runtime/wit/internal.wit b/runtime/wit/internal.wit index 08999973..365b003a 100644 --- a/runtime/wit/internal.wit +++ b/runtime/wit/internal.wit @@ -119,8 +119,9 @@ interface lifecycle { record boot-config { /// The home origin, as an absolute URL without a trailing slash. - /// Release artifacts and, until installation lands, app bundles are - /// fetched from it. + /// It may carry a path (a GitHub Pages project site is served + /// under `//`). Release artifacts and, until installation + /// lands, app bundles are fetched from it. home-origin: string, /// The device this worker is: the glue's sessionStorage anchor, or /// an id the glue minted for a fresh device. The glue names the diff --git a/web/boot.ts b/web/boot.ts index 388f0cdf..d40f9e4b 100644 --- a/web/boot.ts +++ b/web/boot.ts @@ -257,7 +257,10 @@ fetch(new URL("config.json", location.href), { cache: "no-store" }) control.postMessage({ t: "hello", device, - homeOrigin: location.origin, + // The directory this page is served from, not `location.origin`: a + // GitHub Pages project site lives under `//`, and the kernel + // fetches `{home-origin}/apps/...`, so the prefix must be kept. + homeOrigin: new URL(".", location.href).href.replace(/\/$/, ""), relay, // The OAuth redirect (`lifecycle.boot-config.page-url`): this page's // URL without query or fragment, which is where the popup comes back diff --git a/web/worker.ts b/web/worker.ts index adb005f4..c2a9bec9 100644 --- a/web/worker.ts +++ b/web/worker.ts @@ -262,8 +262,8 @@ const ready: Promise = (async () => { driveOauth: string | undefined; }, ) => Promise; - // The home origin without a trailing slash, per `lifecycle.boot-config`. - // `location.origin` is spelled that way, and every tab that can reach this + // The home origin without a trailing slash, per `lifecycle.boot-config`; + // the tab derives it from its own URL, and every tab that can reach this // worker is on the home origin by construction. // `option` lowers as `T | undefined` (m1-context.md "Value // mapping"), so an absent base is passed as the absence itself rather