From 64b6b2d2a6f4f030579e34705f214aa56a1dd7ec Mon Sep 17 00:00:00 2001 From: Kresna Date: Sat, 8 Aug 2026 14:58:33 +0700 Subject: [PATCH] fix(maps): add transformRequest to proxy ALL OFM URLs through /ofm/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fetchResolvedStyle rewrites URLs in the style object but MapLibre still makes its own fetches for TileJSON (when url is present on a vector source), glyphs, and sprites — bypassing the proxy and hitting the broken Singapore CDN edge directly. transformRequest intercepts EVERY URL MapLibre dispatches (including from tile Web Workers) and rewrites tiles.openfreemap.org/* to goodwebtools.com/ofm/*, ensuring all OFM traffic goes through our Cloudflare Worker regardless of what the style object contains. This is the definitive safety net for the blank map bug. Co-Authored-By: Claude Sonnet 4.6 --- src/islands/maps/MapExplorer.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/islands/maps/MapExplorer.tsx b/src/islands/maps/MapExplorer.tsx index cf12af2..cbab136 100644 --- a/src/islands/maps/MapExplorer.tsx +++ b/src/islands/maps/MapExplorer.tsx @@ -192,6 +192,19 @@ export default function MapExplorer({ lang = 'en' }: { lang?: Lang }) { // never needs its own TileJSON fetch (avoids stale CDN edge responses). const styleInput = await fetchResolvedStyle(initialUrl); if (cancelled || !containerRef.current) return; + // Rewrite every OpenFreeMap URL that MapLibre would fetch on its own + // (TileJSON, vector/raster tiles, glyphs, sprites) through our /ofm/ proxy. + // This is the definitive safety net: even if fetchResolvedStyle leaves a + // raw OFM url in the source config, transformRequest rewrites it before + // any network request is dispatched — including requests from tile workers. + const OFM_ORIGIN = 'https://tiles.openfreemap.org/'; + const ofmProxyBase = `${location.origin}/ofm/`; + const transformRequest = (url: string) => { + if (url.startsWith(OFM_ORIGIN)) { + return { url: ofmProxyBase + url.slice(OFM_ORIGIN.length) }; + } + }; + const map = new ml.Map({ container: containerRef.current, // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -200,6 +213,7 @@ export default function MapExplorer({ lang = 'en' }: { lang?: Lang }) { zoom: 3, minZoom: 0, maxZoom: 20, + transformRequest, }); map.addControl(new ml.NavigationControl(), 'top-right'); // Cap GeolocateControl zoom at 14 — the vector tile source's maxzoom is 14;