maplibre-cartography
Cartographic principles for MapLibre GL JS — label and symbol legibility on imagery vs. vector basemaps, figure-ground for point…
Getting a MapLibre GL JS source to actually render — TileJSON `url` versus hand-wired `tiles` templates, matching `source-layer` names to the tile schema, layer order and inserting below labels, `promoteId` and the feature ids that feature state needs, and the CORS and glyph
$ npx -y skills add maplibre/maplibre-agent-skills --skill maplibre-source-wiring --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/maplibre-source-wiringContext preview
The summary Claude sees to decide when to auto-load this skill.
Getting a MapLibre GL JS source to actually render — TileJSON `url` versus hand-wired `tiles` templates, matching `source-layer` names to the tile schema, layer order and inserting below labels, `promoteId` and the feature ids that feature state needs, and the CORS and glyph
name: maplibre-source-wiring description: Getting a MapLibre GL JS source to actually render — TileJSON `url` versus hand-wired `tiles` templates, matching `source-layer` names to the tile schema, layer order and inserting below labels, `promoteId` and the feature ids that feature state needs, and the CORS and glyph failures behind a blank map. Use when a source is configured but nothing is drawing, or when setFeatureState does nothing. status: verified
You have a tile URL or a data file and a style, and the map is blank, drawing at the wrong scale, or drawing in the wrong order. This skill covers connecting a source to a style correctly, and the failure modes that look identical from the outside.
The source is already configured and the map is wrong in a way that produces no error. These are symptoms as you would observe them, before you know the cause:
at its TileJSON instead of hand-writing `tiles`
**Not this skill.** Text in the wrong font, missing scripts, or self-hosting glyph PBFs — [maplibre-fonts-glyphs](../maplibre-fonts-glyphs/SKILL.md). Deciding the colors, type, and drawing order of a style you are designing — [maplibre-cartography](../maplibre-cartography/SKILL.md). Deciding whether a dataset belongs in GeoJSON or vector tiles at all — [maplibre-tile-sources](../maplibre-tile-sources/SKILL.md).
Tiles are addressed by zoom (Z), column (X), and row (Y) — a universal scheme across raster and vector tile sources (see [the OpenStreetMap wiki](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames) for more information). In a MapLibre source, you reference tiles either directly via a `tiles` URL template or via a `url` pointing to a TileJSON endpoint.
**When a TileJSON endpoint is available, prefer `url`.** MapLibre fetches the document and reads the tile URL template, zoom range, bounds, attribution, and (for vector tiles) the available source-layers automatically. Tile servers like Martin and tileserver-gl generate TileJSON endpoints for every tileset they serve, as do many hosted providers.
When no TileJSON endpoint exists — for example, a raw raster tile service that gives you a URL template directly — use the `tiles` array and specify any metadata (minzoom, maxzoom, attribution) in the source definition yourself.
**`url` to a TileJSON endpoint:**
{
"type": "vector",
"url": "https://example.com/tiles.json"
}**`tiles` array:**
{
"type": "vector",
"tiles": ["https://example.com/tiles/{z}/{x}/{y}.pbf"],
"minzoom": 0,
"maxzoom": 14
}`{z}`, `{x}` and `{y}` are tokens MapLibre replaces with each tile's zoom, column and row before it makes a request. A template pasted into a browser with the braces still in it asks for no real tile, so its status code says nothing about the server. To check the server by hand, request a real tile inside the source's zoom range, such as `/0/0/0.pbf`.
The cost of hand-wiring `tiles` is that MapLibre has no zoom range unless you supply one, and will assume `maxzoom: 22` — requesting zoom levels the tileset doesn't contain, which come back empty. This is why `url` is the default advice wherever a TileJSON endpoint exists. (For PMTiles specifically the same rule applies and the consequence is sharper — see [maplibre-pmtiles-patterns](../maplibre-pmtiles-patterns/SKILL.md).)
The most common cause of a custom style rendering nothing against a working tile source is a `source-layer` mismatch.
A vector tile source contains named layers — `transportation`, `water`, `landuse` and so on — and every style layer that draws from it must name one exactly:
{
"id": "roads",
"type": "line",
"source": "basemap",
"source-layer": "transportation"
}`source-layer` is required for vector sources and must match the tile schema exactly. A typo or a name from a different schema produces no error and no output — the layer simply draws nothing.
**Find the real names in the TileJSON.** For vector sources, the TileJSON `vector_layers` field lists each available `source-layer`, its attribute fields, and its zoom range. This is the authoritative reference **when it is present** — TileJSON 3.0 requires it for vector tilesets, but 2.x documents predate it and providers are inconsistent about supplying it. Its absence does not mean there is no schema: identify the schema by name (below) and work from its published layer list. If you use a provider's pre-built style URL, the schema is already matched for you; the mismatch only appears when you write your own layers.
When building a custom style you need to know the **tile schema** — the source-layer names and their properties. Common schemas:
Curated guidance for AI assistants building MapLibre applications — covering ecosystem and open-source best practices. Agent skills are markdown files that AI coding assistants read as context.
Cartographic principles for MapLibre GL JS — label and symbol legibility on imagery vs. vector basemaps, figure-ground for point…
Configuring fonts and glyphs for MapLibre GL JS and MapLibre Native — the style's `glyphs` URL, self-hosting or generating font…
Migrating from Mapbox GL JS to MapLibre GL JS — package and import changes, removing the access token, choosing tile sources,…
Serverless vector and raster tiles with PMTiles for MapLibre GL JS — single-file format, HTTP range requests, hosting on…
The step-by-step procedure for running this repo's Promptfoo evals with a generator and a judge over provider APIs. Use when…
How to turn a working session into a MapLibre agent skill — you researched something MapLibre's docs did not cover, got it wrong…