Fully open-source basemap: keyless OSM + Esri reserve with runtime failover (drop CARTO_KEY) - #37
Open
fpietrosanti wants to merge 1 commit into
Open
fpietrosanti wants to merge 1 commit into
fpietrosanti wants to merge 1 commit into
Conversation
…o CARTO_KEY CARTO put its raster basemaps behind API keys (watermark rollout 2026-08-28, enforcement 2026-09-23). The current answer - a CARTO_KEY GitHub secret injected at deploy time - has structural downsides on a static site: the key is world-readable in the served JS (anyone can copy it and burn the quota), forks and local checkouts render watermark tiles, deploys hard-fail when the secret is missing, and the project gains a billing dependency. This PR makes the basemap fully open and keyless: - Primary: OpenStreetMap standard raster (OSMF, native z19). The familiar positron-like light-gray canvas is recreated with a CSS grayscale filter (.basemap-muted). - Labels above polygons: OSM bakes labels into the raster, so the SAME tiles are re-drawn on a dedicated pane blended with mix-blend-mode:darken + a midtone-crushing filter - only place names and admin borders emerge above the data. Same URLs => served from the browser HTTP cache, zero extra tile requests to OSM. @supports guard: browsers without blending simply hide the overlay. - Runtime failover: after 8 tileerror events the map swaps to the keyless Esri World Light Gray reserve (Base + Reference labels). Encoded traps: Esri axis order is /tile/{z}/{y}/{x} (INVERTED vs slippy) and native tiles stop at z16 (maxNativeZoom). - HQ PNG export follows the active basemap (template-based tile fetching; the label pass uses canvas globalCompositeOperation=darken to match the on-screen look) and updates its attribution line. - deploy.yml: CARTO_KEY injection step removed - deploys need no secret, forks render exactly what production renders. - tests/test_basemap.py: functional battery. Structural: keyless-only templates, axis-order rule per host, blend CSS contract, failover wiring, preconnect alignment. Functional: real LAND tiles (Rome, Milan) for primary AND reserve - HTTP 200 + image/* + minimum size + the anti-placeholder check (two coordinates MUST return different bytes; a watermark is identical everywhere - the only check that catches breakage hidden behind HTTP 200). Battle-tested: mxmap.it (the Italian Osservatorio fork) runs exactly this stack in production since 2026-09-29, with the battery green in CI and a daily scheduled run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
CARTO put its raster basemaps behind API keys (watermark rollout 2026-08-28, enforcement 2026-09-23). The current mitigation — a
CARTO_KEYGitHub secretsed-injected at deploy — has structural downsides on a static site:__CARTO_KEY__literal);This PR proposes going fully open-source and keyless instead. On mxmap.it (the Italian Osservatorio fork of this project) we made this exact choice — OSM instead of private CARTO API keys — and have been running this stack in production since 2026-09-29.
What
/{z}/{x}/{y}). Positron-like light-gray look recreated via CSS grayscale (.basemap-muted)mix-blend-mode: darken+ a midtone-crushing filter: only place names/borders emerge above the data. Same URLs ⇒ browser HTTP cache ⇒ zero extra requests to OSM.@supportsguard for old browserstileerror→ automatic swap to the keyless Esri World Light Gray reserve (Base + Reference on the blend pane). Encoded traps: Esri axis order/tile/{z}/{y}/{x}is inverted vs slippy, native max z16 (maxNativeZoom). Manual hook:window.__forceBasemapFailover()globalCompositeOperation='darken'; attribution line updates accordinglyCARTO_KEYinjection step removed — no secret needed, forks render exactly what production rendersimage/*+ min size + the anti-placeholder check: two coordinates MUST return different bytes. A watermark is identical everywhere; it is the only check that catches breakage hidden behind HTTP 200 (exactly how the CARTO change broke the map silently)Verification
providers.htmlfrom this branch: 32/32 OSM tiles loaded, muted filter and blend pane active (computed styles verified), zero console errors; after__forceBasemapFailover(): 32/32 Esri tiles loaded, 16 Reference label tiles on the blend pane, zero residual OSM tiles.node --check js/map-shared.jsclean;ruff format --check+ruff checkclean on the new test.Notes for review
© OpenStreetMap contributors, also in exports); the label overlay adds no requests (same URLs, cached); no prefetching. If you prefer to keep network tests out of PR CI, the battery can be moved to a scheduled workflow — happy to adjust.{r}/@2x variant — slight sharpness loss on HiDPI vs CARTO. We judged it a fair trade for zero keys/costs; the CSS filter hides most of it.🤖 Generated with Claude Code