Skip to content

Root Configuration

The root configuration is the top-level structure of your maplibre-yaml file. It defines global settings, reusable definitions, and pages.

config: # Global configuration (optional)
title: ...
defaultMapStyle: ...
layers: # Named layer definitions (optional)
layerName: ...
sources: # Named source definitions (optional)
sourceName: ...
pages: # Page definitions (required, min: 1)
- path: ...
blocks: ...

Optional top-level settings that apply across all pages.

PropertyTypeRequiredDefaultDescription
titlestringNo-Application title
descriptionstringNo-Application description
defaultMapStylestring (URL)No-Default map style for all maps
theme"light" | "dark"No"light"Default theme
dataFetchingobjectNo-Data fetching configuration

Configure how data is fetched across all maps:

PropertyTypeRequiredDefaultDescription
defaultStrategy"runtime" | "build" | "hybrid"No"runtime"When to fetch data
timeoutnumberNo30000Timeout in milliseconds (min: 1000)
retryAttemptsnumberNo3Number of retry attempts (min: 0)
config:
title: "My Map Application"
description: "Interactive maps and data visualization"
defaultMapStyle: "https://demotiles.maplibre.org/style.json"
theme: dark
dataFetching:
defaultStrategy: build
timeout: 15000
retryAttempts: 5

Define layers once and reference them in multiple maps using $ref.

layers:
earthquakes:
id: earthquakes
type: circle
source:
type: geojson
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
paint:
circle-radius: 6
circle-color: "#e74c3c"
cities:
id: cities
type: symbol
source:
type: geojson
url: "https://example.com/cities.geojson"
layout:
text-field: ["get", "name"]
text-size: 12
pages:
- path: "/"
blocks:
- type: map
id: map1
config: {...}
layers:
- $ref: "#/layers/earthquakes"
- $ref: "#/layers/cities"

You can define named sources in two places and reference them from layers.

Define sources at the map block level and reference them by their bare name across multiple layers in that block.

pages:
- path: "/"
title: "Home"
blocks:
- type: map
id: map1
config: {...}
sources:
earthquakeData:
type: geojson
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
refresh:
refreshInterval: 300000 # 5 minutes
updateStrategy: merge
updateKey: id
layers:
- id: quakes
type: circle
source: earthquakeData
paint:
circle-radius: 6

Layers reference a block-level named source with its bare name (source: earthquakeData).

Sources declared in the root sources: map (next to pages:) can be shared across maps and reached from a layer’s source: using a $ref object:

sources:
boundaries:
type: geojson
url: "https://example.com/boundaries.geojson"
pages:
- path: "/"
title: "Home"
blocks:
- type: map
id: map1
config: {...}
layers:
- id: outline
type: line
source: { $ref: "#/sources/boundaries" }
paint:
line-color: "#333"

The $ref is resolved at parse time against the root sources: map. A dangling reference (unknown source name) produces a clear error with a did-you-mean suggestion, for example:

Source reference not found: #/sources/boundary. Did you mean "#/sources/boundaries"? Defined sources: boundaries.

The bare-string path form source: "#/sources/name" is not resolved — it validates as a plain string but the source will never be found at render time. Use the { $ref: "#/sources/name" } object form for root-level sources, or a bare name for block-level sources.

Required array of page configurations. At least one page must be defined.

pages:
- path: "/"
title: "Home"
blocks: [...]
- path: "/map"
title: "Interactive Map"
blocks: [...]

See Pages & Blocks for detailed page configuration.

# Global configuration
config:
title: "Earthquake Monitoring"
description: "Real-time earthquake visualization"
defaultMapStyle: "https://demotiles.maplibre.org/style.json"
theme: dark
dataFetching:
defaultStrategy: runtime
timeout: 10000
retryAttempts: 3
# Reusable layer definitions
layers:
earthquakes:
id: earthquakes
type: circle
source:
type: geojson
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
refresh:
refreshInterval: 300000
updateStrategy: replace
paint:
circle-radius:
- interpolate
- ["linear"]
- ["get", "mag"]
- 0
- 2
- 8
- 20
circle-color:
- interpolate
- ["linear"]
- ["get", "mag"]
- 0
- "#ffffcc"
- 4
- "#fd8d3c"
- 8
- "#800026"
circle-opacity: 0.8
# Pages
pages:
- path: "/"
title: "Earthquake Map"
blocks:
- type: content
content:
- h1: [{ str: "Global Earthquake Activity" }]
- p: [{ str: "Real-time earthquake data from USGS" }]
- type: map
id: main-map
config:
center: [0, 20]
zoom: 2
pitch: 0
sources:
tectonicPlates:
type: geojson
url: "https://raw.githubusercontent.com/fraxen/tectonicplates/master/GeoJSON/PB2002_plates.json"
layers:
- $ref: "#/layers/earthquakes"
- id: plates
type: line
source: tectonicPlates
paint:
line-color: "#ffffff"
line-width: 2
line-opacity: 0.5
controls:
navigation: true
scale: true
legend:
title: "Magnitude"
items:
- label: "< 4.0"
color: "#ffffcc"
- label: "4.0 - 6.0"
color: "#fd8d3c"
- label: "> 6.0"
color: "#800026"
- path: "/story"
title: "Earthquake Story"
blocks:
- type: scrollytelling
id: story
config:
center: [0, 20]
zoom: 2
chapters:
- id: intro
title: "Introduction"
description: "Understanding global seismic activity"
center: [0, 20]
zoom: 2
- id: pacific
title: "Ring of Fire"
description: "The Pacific Ring of Fire accounts for 90% of earthquakes"
center: [155, 10]
zoom: 4

When using $ref (as an object), the supported formats are:

  • #/layers/layerName - Reference a named layer (in a block’s layers array)
  • #/sources/sourceName - Reference a root-level named source (in a layer’s source: field)

References are resolved at parse time and replaced with the actual definition. Note that $ref must always be a YAML mapping with a $ref key — a plain string like "#/layers/layerName" is not treated as a reference. For sources you can either reference a root-level source with source: { $ref: "#/sources/name" } or reference a block-level source by its bare name (source: name).

The root schema enforces:

  • At least one page: pages array must have minimum 1 item
  • Valid URLs: defaultMapStyle must be a valid URL if provided
  • Valid enums: theme, defaultStrategy must be valid enum values
  • Numeric constraints: timeout ≥ 1000, retryAttempts ≥ 0
pages: Array must have at least 1 element(s)
config.defaultMapStyle: Invalid URL format
config.theme: Invalid enum value. Expected 'light' | 'dark', received 'blue'
config.dataFetching.timeout: Value must be >= 1000
import { type RootConfig, type GlobalConfig } from '@maplibre-yaml/core/schemas';
const config: RootConfig = {
config: {
title: "My App",
defaultMapStyle: "https://example.com/style.json",
theme: "dark"
},
pages: [
{
path: "/",
title: "Home",
blocks: []
}
]
};