Skip to content

Custom Styling

Build your own style on top of MFD_standard.

Start from a hosted style

Fetch our style as a starting point, modify, host yourself.

bash
curl 'https://api.mapsfordevs.com/styles/standard.json?key=mfd_pub_xxx' \
  > my-style.json

Edit colours, fonts, layer ordering. Keep sources pointing at our tile URL.

Minimal custom style

json
{
  "version": 8,
  "name": "My Map",
  "glyphs": "https://api.mapsfordevs.com/fonts/{fontstack}/{range}.pbf?key=mfd_pub_xxx",
  "sprite": "https://api.mapsfordevs.com/sprites/standard?key=mfd_pub_xxx",
  "sources": {
    "mfd": {
      "type": "vector",
      "tiles": ["https://tiles.mapsfordevs.com/tiles/{z}/{x}/{y}.pbf?key=mfd_pub_xxx"],
      "minzoom": 0,
      "maxzoom": 17,
      "attribution": "© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> · © MapsForDevs"
    }
  },
  "layers": [
    {
      "id": "background",
      "type": "background",
      "paint": { "background-color": "#f5f5f0" }
    },
    {
      "id": "water",
      "type": "fill",
      "source": "mfd",
      "source-layer": "water",
      "paint": { "fill-color": "#a3cfff" }
    },
    {
      "id": "roads",
      "type": "line",
      "source": "mfd",
      "source-layer": "transportation",
      "paint": {
        "line-color": ["match", ["get", "class"],
          "motorway", "#e89e3c",
          "trunk",    "#f0b95f",
          "primary",  "#fdd8a4",
          "#cccccc"
        ],
        "line-width": ["interpolate", ["linear"], ["zoom"],
          5, 0.5,
          14, 4,
          18, 24
        ]
      }
    },
    {
      "id": "place_label",
      "type": "symbol",
      "source": "mfd",
      "source-layer": "place",
      "filter": ["in", ["get", "class"], ["literal", ["city", "town"]]],
      "layout": {
        "text-field": ["coalesce", ["get", "name:latin"], ["get", "name"]],
        "text-font": ["Noto Sans Regular"],
        "text-size": ["interpolate", ["linear"], ["zoom"], 4, 10, 12, 18]
      },
      "paint": {
        "text-color": "#333",
        "text-halo-color": "#fff",
        "text-halo-width": 1.5
      }
    }
  ]
}

Layer ordering (bottom → top)

Following this order produces a clean cartographic stack:

  1. background
  2. landcover (forest, sand)
  3. landuse (parks, residential)
  4. water polygons
  5. waterway lines
  6. boundary (country, admin)
  7. transportation casing (wider, dark) lines
  8. transportation fill (narrower, light) lines
  9. building polygons / extrusions
  10. transportation_name symbol
  11. poi_label symbol
  12. place_label symbol

Fonts

Available text-font stacks:

Font stackNotes
Noto Sans RegularDefault Latin
Noto Sans BoldHeadings, country names
Noto Sans ItalicWater bodies (cartographic convention)
Noto Sans Arabic RegularRTL languages
Noto Sans CJK JP RegularJapanese
Noto Sans CJK SC RegularSimplified Chinese
Noto Sans CJK KR RegularKorean
Noto Sans Devanagari RegularHindi, Marathi, Nepali
Noto Emoji RegularEmoji glyphs

Use a font fallback stack:

json
"text-font": ["Noto Sans Regular", "Noto Sans Arabic Regular", "Noto Emoji Regular"]

Sprites

Hosted sprite sheet at /sprites/standard?key=…. To add your own icons, host a custom sprite and reference it:

json
"sprite": "https://your-cdn.example.com/my-sprites/v1"

Format: standard MapBox sprite (.png + .json).

Hot-reload during development

Maputnik (free, browser-based) is the canonical visual editor:

bash
npx maputnik -s my-style.json

It edits the JSON in place. Save → reload your app.

Validate

bash
npx @maplibre/maplibre-gl-style-spec validate my-style.json