Data Sources
maplibre-yaml supports multiple ways to provide data to your layers: inline GeoJSON, remote URLs, and streaming connections.
Inline data
Section titled “Inline data”For small, static datasets, embed the GeoJSON directly:
source: type: geojson data: type: FeatureCollection features: - type: Feature geometry: type: Point coordinates: [-74.006, 40.7128] properties: name: "New York"Remote URL
Section titled “Remote URL”Load GeoJSON from any URL:
source: type: geojson url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"CORS considerations
Section titled “CORS considerations”When loading from remote URLs, the server must allow cross-origin requests (CORS). If you see errors, the API may not support browser requests.
Solutions:
- Use APIs that support CORS (like USGS earthquake feed)
- Set up a proxy server
- Host the data yourself
Caching
Section titled “Caching”Control how fetched data is cached:
source: type: geojson url: "https://api.example.com/data.geojson" cache: enabled: true # Enable caching (default) ttl: 300000 # Cache for 5 minutes (milliseconds)Cache behavior
Section titled “Cache behavior”| Scenario | Behavior |
|---|---|
| First request | Fetch from network, store in cache |
| Subsequent (within TTL) | Return cached data immediately |
| After TTL expires | Fetch fresh data, update cache |
enabled: false | Always fetch from network |
Loading states
Section titled “Loading states”Show feedback while data loads:
source: type: geojson url: "https://api.example.com/data.geojson" loading: enabled: true message: "Loading earthquake data..."When enabled, maplibre-yaml shows a spinner overlay while fetching data and an error message if the fetch fails.
Handling errors programmatically
Section titled “Handling errors programmatically”const renderer = new MapRenderer(container, config);
renderer.on("layer:loading", ({ layerId }) => { console.log(`Loading ${layerId}...`);});
renderer.on("layer:loaded", ({ layerId, featureCount, fromCache }) => { console.log(`Loaded ${featureCount} features (cached: ${fromCache})`);});
renderer.on("layer:error", ({ layerId, error }) => { console.error(`Failed to load ${layerId}:`, error.message);});Clustering
Section titled “Clustering”For point datasets with many features, enable clustering:
source: type: geojson url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson" cluster: true clusterRadius: 50 # Cluster points within 50px clusterMaxZoom: 14 # Stop clustering at zoom 14Then style clustered and unclustered points separately:
layers: # Clustered points - id: clusters type: circle source: earthquakes filter: ["has", "point_count"] paint: circle-radius: - step - ["get", "point_count"] - 20 # Default size - 100 - 30 # Larger for 100+ points - 750 - 40 # Even larger for 750+ circle-color: "#3b82f6"
# Cluster count labels - id: cluster-count type: symbol source: earthquakes filter: ["has", "point_count"] layout: text-field: "{point_count_abbreviated}" text-size: 12
# Individual points - id: unclustered type: circle source: earthquakes filter: ["!", ["has", "point_count"]] paint: circle-radius: 6 circle-color: "#ef4444"Named Sources
Section titled “Named Sources”Define sources at the block level and reference them by name across multiple layers. This avoids duplicating source definitions and is the recommended approach when multiple layers share the same data.
type: mapid: earthquake-mapconfig: center: [-120, 35] zoom: 6 mapStyle: "https://demotiles.maplibre.org/style.json"
sources: quakes: type: geojson url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson" cluster: true clusterRadius: 50 clusterMaxZoom: 14
layers: - id: clusters type: circle source: quakes filter: ["has", "point_count"] paint: circle-radius: - step - ["get", "point_count"] - 20 - 100 - 30 circle-color: "#3b82f6"
- id: cluster-count type: symbol source: quakes filter: ["has", "point_count"] layout: text-field: "{point_count_abbreviated}" text-size: 12
- id: unclustered type: circle source: quakes filter: ["!", ["has", "point_count"]] paint: circle-radius: 6 circle-color: "#ef4444"Named sources are added to the map before layers, so any layer can reference them by string ID. Inline sources on individual layers still work — the two approaches can be mixed freely.