Host your own basemap
A basemap can be one PMTiles file on your own site, served by the same static
host as the page, with no tile server and no API key. Point mapStyle: at the
file and maplibre-yaml builds the whole Protomaps
basemap style around it, in the page. Use it when you don’t want your map to
depend on a tile service, or need it to keep working for years.
# A Protomaps basemap from one .pmtiles file: no API key, no tile server,# no page JavaScript. The file is a ~0.6 MB extract of DUMBO and Brooklyn# Heights from the Protomaps planet build; data © OpenStreetMap contributors.type: mapid: protomaps-basemap-democonfig: center: [-73.9935, 40.6995] zoom: 14.5 minZoom: 12 maxBounds: [-74.02, 40.68, -73.97, 40.715] mapStyle: pmtiles: /gallery-assets/protomaps/brooklyn.pmtiles flavor: lightlayers: - id: brooklyn-bridge-park type: circle source: type: geojson data: { type: Point, coordinates: [-73.9967, 40.7003] } paint: circle-radius: 8 circle-color: "#e63946" circle-stroke-color: "#ffffff" circle-stroke-width: 2Quick start
Section titled “Quick start”-
Cut a regional extract from the Protomaps daily planet build with the
pmtilescommand-line tool:Terminal window pmtiles extract https://build.protomaps.com/<date>.pmtiles nyc.pmtiles \--bbox=-74.26,40.48,-73.70,40.92 --maxzoom=13Pick
<date>from build.protomaps.com. The tool reads only the part of the planet it needs. This extract of New York City is about 12 MB. -
Put the file in your site:
public/data/nyc.pmtilesin an Astro or Vite project, or adata/folder next to your HTML page. -
Use it from your document:
type: mapid: nycconfig:center: [-73.98, 40.71]zoom: 12mapStyle: data/nyc.pmtilesYou should see a light street map of New York, labelled in the page’s language where OpenStreetMap has the names.
Choose a flavor and language
Section titled “Choose a flavor and language”Write mapStyle: as a block to choose:
config: center: [-73.98, 40.71] zoom: 12 mapStyle: pmtiles: data/nyc.pmtiles flavor: light # light (default), dark, white, grayscale or black lang: en # optional: label languagelang: picks the language labels are drawn in where OpenStreetMap has the
name (en, es, fr, de, ja, zh-Hans, and about 40 more). Without
it, labels follow the page’s lang when the basemap has that language, and
English otherwise. Arabic, Hebrew, Persian and Urdu labels (ar, he, fa,
ur) are written right to left: maplibre-gl 6.9 and later draw them as they
are; with an older maplibre-gl, maplibre-yaml loads MapLibre’s right-to-left
text plugin from unpkg.com the first time such a label is drawn.
Keep the file small
Section titled “Keep the file small”Each extra zoom level makes an extract roughly three times bigger: the New
York extract above is about 12 MB at --maxzoom=13 and about 95 MB with
every zoom level (to 15). Zoom 13 is enough for a city map: MapLibre draws
closer zooms from the zoom-13 tiles, with fewer minor street names.
That matters on GitHub: its web upload (“Add file → Upload files”) takes
files up to 25 MB, git push warns above 50 MB and refuses files over
100 MB, and a GitHub Pages site is limited to 1 GB. To go smaller, cut a
tighter --bbox around the area you show, or lower --maxzoom (12 still
reads well for a whole city). For larger areas, use a host meant for big
files, such as an object store (S3, R2).
Paths and hosting
Section titled “Paths and hosting”-
A relative
pmtiles:path resolves against the page, andbaseapplies to it like to every other path, so the same YAML works on a GitHub Pages project site (<ml-map base="/my-repo/">; the Astro components set it from your site’sbase). A full URL (https://…/nyc.pmtiles) or apmtiles://URL works too. -
The file is read with range requests, like any PMTiles file. Preview locally with
npx serveorastro dev;python -m http.serverdoesn’t support them (Publishing › Large files). -
Labels and icons come from Protomaps’ hosted fonts and sprites (
protomaps.github.io/basemaps-assets). To host those yourself too, copy the fonts and the sprite for your flavor from basemaps-assets and name them:mapStyle:pmtiles: data/nyc.pmtilesglyphs: fonts/{fontstack}/{range}.pbfsprite: sprites/v4/light -
Attribution to OpenStreetMap and Protomaps is added to the map.
Your layers on top
Section titled “Your layers on top”Your layers draw on top of the basemap, as with any basemap. before: can
name a basemap layer to slide one underneath, for example
before: places_subplace to keep neighbourhood names above your data. A
story chapter can restyle basemap layers by id (water, earth,
landuse_park, roads_minor, buildings …); map.getStyle().layers lists
them all.
A full style.json of your own
Section titled “A full style.json of your own”To change the basemap’s design beyond a flavor, use a style file instead.
Generate one for your file (Protomaps’
style generator, or
mlym emit on a document using the form above), save it as style.json
beside the file, edit it, and point its source at the file:
"url": "pmtiles://nyc.pmtiles". Then:
config: mapStyle: basemap/style.json # public/basemap/ in an Astro or Vite siteRelative URLs inside the style resolve against the style (PMTiles inside a basemap style).
Troubleshooting
Section titled “Troubleshooting”When something is wrong the map shows a notice instead of a blank basemap:
- “The basemap didn’t load:” followed by the reason: the file isn’t
there (check the path and
base), or the server doesn’t support range requests. - “…doesn’t look like a Protomaps basemap”: the file holds other tiles.
Your own tiles go under
sources:with layers (PMTiles). - “…built with an older tile schema … only land and water draw”: cut a new extract from build.protomaps.com.
- No labels or icons, and the notice names the fonts or icons: the Protomaps asset host isn’t reachable from the page; host the assets yourself (above).
In a format v2 document the same forms go in
style.basemap:. Exporting this basemap to a style.json:
Large-data files in an exported style.