Keyboard shortcuts

Press โ† or โ†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Examples

The following examples are based on the official examples in MapLibre Docs. They are defined in the examples directory of the repository and automatically bundeled in the docs.

Add a raster tile source ๐ŸŒ ๐Ÿ”—

Add a third-party raster source to the map.

Add a WMS source ๐ŸŒ ๐Ÿ”—

Add an external Web Map Service raster layer to the map.

Check if WebGL is supported ๐ŸŒ ๐Ÿ”—

Check for WebGL browser support.

Display a globe with an atmosphere ๐ŸŒ ๐Ÿ”—

Display a globe with an atmosphere.

Display a map ๐ŸŒ ๐Ÿ”—

Initialize a map with Yew and the unofficial MapLibre GL JS Rust bindings.

Display a map with HTMLElement ๐ŸŒ ๐Ÿ”—

Initialize a map with Yew and the unofficial MapLibre GL JS Rust bindings by passing an HTMLElement reference.

Display a map with MLT ๐ŸŒ ๐Ÿ”—

Initialize a map in an HTML element with MapLibre GL JS. This example is using a style that uses MLT (MapLibre Tiles). The example is very similar to the regular one except the tiles are in a different encoding.

Display a satellite map ๐ŸŒ ๐Ÿ”—

Display a satellite raster baselayer.

Display a non-interactive map ๐ŸŒ ๐Ÿ”—

Create a map without interactivity.

Set pitch and bearing ๐ŸŒ ๐Ÿ”—

Initialize a map with pitch and bearing camera options.

Style labels with local fonts ๐ŸŒ ๐Ÿ”—

Apply local fonts to your styleโ€™s text labels. This option is suitable if you donโ€™t need every user to see exactly the same font, or if you want to avoid relying on a third-party content delivery network (CDN). For maximum compatibility, the text-font property should include fonts commonly found on multiple platforms.

Style labels with Web fonts ๐ŸŒ ๐Ÿ”—

Apply Web fonts to your styleโ€™s text labels. Unlike signed distance field (SDF) glyph sets, Web fonts are available from a variety of providers, or your can make your own using popular tools. This option is suitable for fonts that are only available through a third-party content delivery network (CDN) for technical or legal reasons, as well as fonts that are incompatible with SDF, such as variable fonts. For compatibility with Android and iOS applications, specify equivalent fonts in the styleโ€™s font-faces property.

Add a raster tile source ๐Ÿ”—

Add a third-party raster source to the map.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_style(serde_json::json!({
                "version": 8,
                "sources": {
                    "raster-tiles": {
                        "type": "raster",
                        "tiles": ["https://tile.openstreetmap.org/{z}/{x}/{y}.png"],
                        "tileSize": 256,
                        "minzoom": 0,
                        "maxzoom": 19
                    }
                },
                "layers": [
                    {
                        "id": "simple-tiles",
                        "type": "raster",
                        "source": "raster-tiles",
                        "attribution": "ยฉ OpenStreetMap contributors",
                    }
                ],
                "id": "blank"
            }))
            .with_center([0., 0.])
            .with_zoom(0.)
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Add a raster tile source</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Add a WMS source ๐Ÿ”—

Add an external Web Map Service raster layer to the map.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_style(serde_json::json!({
                "version": 8,
                "sources": {
                    "wms-test-source": {
                        "type": "raster",
                        // use the tiles option to specify a WMS tile source URL
                        // https://maplibre.org/maplibre-style-spec/sources/
                        "tiles": [
                            "https://ows.terrestris.de/osm/service?service=WMS&request=GetMap&version=1.1.1&layers=TOPO-WMS%2COSM-Overlay-WMS&styles=&format=image%2Fpng&transparent=true&info_format=text%2Fhtml&tiled=false&srs=EPSG:3857&bbox={bbox-epsg-3857}&width=256&height=256"
                        ],
                        "tileSize": 256
                    }
                },
                "layers": [{
                    "id": "wms-test-layer",
                    "type": "raster",
                    "source": "wms-test-source",
                    "paint": {}
                }]
            }))
            .with_center([-74.5447, 40.6892])
            .with_zoom(8.)
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Add a WMS source source</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Check if WebGL is supported ๐Ÿ”—

Check for WebGL browser support.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use web_sys::{HtmlCanvasElement, js_sys::Reflect, wasm_bindgen::JsValue};
use yew::{Html, function_component, html, use_effect, use_state};

fn is_webgl_supported() -> bool {
    let window = web_sys::window().expect("Window should be available");
    let document = window.document().expect("The document should be available");

    // Check if the class is directly missing
    if let Err(_) = Reflect::get(&window, &"WebGLRenderingContext".into()) {
        return false;
    }

    let canvas: HtmlCanvasElement = Into::<JsValue>::into(
        document
            .create_element("canvas")
            .expect("Creating an element should work"),
    )
    .into();

    // Obtain context
    let context = match (canvas.get_context("webgl2"), canvas.get_context("webgl")) {
        // If a JsException is raised, then it is supported but disabled
        (Err(_), _) => return false,
        (_, Err(_)) => return false,
        // No context available, then it is unsupported
        (Ok(None), Ok(None)) => return false,
        // Context is available
        (Ok(Some(webgl2_context)), _) => webgl2_context,
        (Ok(None), Ok(Some(webgl_context))) => webgl_context,
    };

    // Check if the context was properly initialized
    Reflect::get(&context, &"getParameter".into()).is_ok_and(|v| {
        v.js_typeof()
            .as_string()
            .expect("Result should be a string")
            == "function"
    })
}

#[function_component(App)]
fn app() -> Html {
    let webgl_supported = is_webgl_supported();
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        if webgl_supported {
            MapOptions::new("map")
                .with_style("https://demotiles.maplibre.org/style.json")
                .with_center([-74.5, 40.])
                .with_zoom(2.)
                .build()
                .expect("Creating a map should work");
            map_rendered.set(true);
        }
    });
    html! { if webgl_supported { <div id="map"></div> } else { <p>{"WebGl not supported"}</p> } }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Check if WebGL is supported</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Display a globe with an atmosphere ๐Ÿ”—

Display a globe with an atmosphere.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_style(serde_json::json!({
                "version": 8,
                "projection": {
                    "type": "globe"
                },
                "sources": {
                    "satellite": {
                        "tiles": ["https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg"],
                        "type": "raster"
                    },
                },
                "layers": [
                    {
                        "id": "Satellite",
                        "type": "raster",
                        "source": "satellite",
                    },
                ],
                "sky": {
                    "atmosphere-blend": [
                        "interpolate",
                        ["linear"],
                        ["zoom"],
                        0, 1,
                        5, 1,
                        7, 0
                    ]
                },
                "light": {
                    "anchor": "map",
                    "position": [1.5, 90, 80]
                }
            }))
            .with_center([137.9150899566626, 36.25956997955441])
            .with_zoom(0.)
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Display a globe with an atmosphere</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }
#map { background: #000 }

Display a map ๐Ÿ”—

Initialize a map with Yew and the unofficial MapLibre GL JS Rust bindings.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_style("https://demotiles.maplibre.org/style.json")
            .with_center([0., 0.])
            .with_zoom(1.0)
            .with_maplibre_logo()
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Display a map</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Display a map with HTMLElement ๐Ÿ”—

Initialize a map with Yew and the unofficial MapLibre GL JS Rust bindings by passing an HTMLElement reference.

// src/main.rs 

use maplibre_gl_js::interface::{HtmlElement, MapOptions};
use yew::{Html, function_component, html, use_effect, use_node_ref, use_state};

#[function_component(App)]
fn app() -> Html {
    let container_ref = use_node_ref();
    let map_rendered = use_state(|| false);

    {
        let container_ref = container_ref.clone();
        use_effect(move || {
            if *map_rendered {
                return;
            }
            let container = container_ref
                .cast::<HtmlElement>()
                .expect("Container should be a valid HtmlElement");
            MapOptions::new(container)
                .with_style("https://demotiles.maplibre.org/style.json")
                .with_center([0., 0.])
                .with_zoom(1.0)
                .with_maplibre_logo()
                .build()
                .expect("Creating a map should work");
            map_rendered.set(true);
        });
    }

    html! { <div ref={container_ref}></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Display a map</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Display a map with MLT ๐Ÿ”—

Initialize a map in an HTML element with MapLibre GL JS. This example is using a style that uses MLT (MapLibre Tiles). The example is very similar to the regular one except the tiles are in a different encoding.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_style("https://demotiles.maplibre.org/tiles-mlt/plain.json")
            .with_center([0., 0.])
            .with_zoom(1.0)
            .with_maplibre_logo()
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Display a map with MLT</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Display a satellite map ๐Ÿ”—

Display a satellite raster baselayer.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_center([137.9150899566626, 36.25956997955441])
            .with_zoom(9.)
            .with_style(serde_json::json!({
                "version": 8,
                "sources": {
                    "satellite": {
                        "type": "raster",
                        "tiles": [
                            "https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg"
                        ],
                        "tileSize": 256
                    }
                },
                "layers": [{
                    "id": "satellite",
                    "type": "raster",
                    "source": "satellite"
                }]
            }))
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Display a satellite map</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Display a non-interactive map ๐Ÿ”—

Create a map without interactivity.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_style("https://demotiles.maplibre.org/style.json")
            .with_center([74.5, 40.])
            .with_zoom(3.)
            .without_interactivity()
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Display a map</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Set pitch and bearing ๐Ÿ”—

Initialize a map with pitch and bearing camera options.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_style("https://demotiles.maplibre.org/style.json")
            .with_center([-73.5804, 45.53483])
            .with_pitch(60)
            .with_bearing(-60)
            .with_zoom(4.0)
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Set pitch and bearing</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Style labels with local fonts ๐Ÿ”—

Apply local fonts to your styleโ€™s text labels. This option is suitable if you donโ€™t need every user to see exactly the same font, or if you want to avoid relying on a third-party content delivery network (CDN). For maximum compatibility, the text-font property should include fonts commonly found on multiple platforms.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_zoom(9.)
            .with_center([137.9150899566626, 36.25956997955441])
            .with_style(serde_json::json!({
                "version": 8,
                "sources": {
                    "satellite": {
                        "type": "raster",
                        "tiles": [
                            "https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg",
                        ],
                        "tileSize": 256,
                    },
                    "places": {
                        "type": "geojson",
                        "data": {
                            "type": "FeatureCollection",
                            "features": [
                                {
                                    "type": "Feature",
                                    "properties": {
                                        "name": "ๅฎ‰ๆ›‡้‡Žๅธ‚",
                                    },
                                    "geometry": {
                                        "type": "Point",
                                        "coordinates": [137.9054972, 36.3044083],
                                    }
                                },
                                {
                                    "type": "Feature",
                                    "properties": {
                                        "name": "ๆพๆœฌๅธ‚",
                                    },
                                    "geometry": {
                                        "type": "Point",
                                        "coordinates": [137.9687141, 36.2382047],
                                    }
                                }
                            ]
                        }
                    }
                },
                "layers": [
                    {
                        "id": "satellite",
                        "type": "raster",
                        "source": "satellite",
                    },
                    {
                        "id": "places",
                        "type": "symbol",
                        "source": "places",
                        "layout": {
                            "text-font": ["Hiragino Mincho ProN", "Noto Serif CJK JP", "MS Mincho"],
                            "text-size": 24,
                            "text-field": ["get", "name"],
                        },
                        "paint": {
                            "text-color": "white",
                        },
                    },
                ],
            }))
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Style labels with local fonts</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }

Style labels with Web fonts ๐Ÿ”—

Apply Web fonts to your styleโ€™s text labels. Unlike signed distance field (SDF) glyph sets, Web fonts are available from a variety of providers, or your can make your own using popular tools. This option is suitable for fonts that are only available through a third-party content delivery network (CDN) for technical or legal reasons, as well as fonts that are incompatible with SDF, such as variable fonts. For compatibility with Android and iOS applications, specify equivalent fonts in the styleโ€™s font-faces property.

// src/main.rs 

use maplibre_gl_js::interface::MapOptions;
use yew::{Html, function_component, html, use_effect, use_state};

#[function_component(App)]
fn app() -> Html {
    let map_rendered = use_state(|| false);
    use_effect(move || {
        if *map_rendered {
            return;
        }
        MapOptions::new("map")
            .with_zoom(9.)
            .with_center([137.9150899566626, 36.25956997955441])
            .with_style(serde_json::json!({
                "version": 8,
                "sources": {
                    "satellite": {
                        "type": "raster",
                        "tiles": [
                            "https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857/default/g/{z}/{y}/{x}.jpg",
                        ],
                        "tileSize": 256,
                    },
                    "places": {
                        "type": "geojson",
                        "data": {
                            "type": "FeatureCollection",
                            "features": [
                                {
                                    "type": "Feature",
                                    "properties": {
                                        "name": "Azumino",
                                    },
                                    "geometry": {
                                        "type": "Point",
                                        "coordinates": [137.9054972, 36.3044083],
                                    }
                                },
                                {
                                    "type": "Feature",
                                    "properties": {
                                        "name": "Matsumoto",
                                    },
                                    "geometry": {
                                        "type": "Point",
                                        "coordinates": [137.9687141, 36.2382047],
                                    }
                                }
                            ]
                        }
                    }
                },
                "layers": [
                    {
                        "id": "satellite",
                        "type": "raster",
                        "source": "satellite",
                    },
                    {
                        "id": "places",
                        "type": "symbol",
                        "source": "places",
                        "layout": {
                            "text-font": ["Rampart One"],
                            "text-size": 24,
                            "text-field": ["get", "name"],
                        },
                        "paint": {
                            "text-color": "white",
                        }
                    }
                ]
            }))
            .build()
            .expect("Creating a map should work");
        map_rendered.set(true);
    });
    html! { <div id="map"></div> }
}

fn main() {
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    console_error_panic_hook::set_once();
    yew::Renderer::<App>::new().render();
}
<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
    <title>Style labels with Web fonts</title>
    <link rel="scss" data-trunk href="scss/style.scss" />
    <script src="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.18.0/dist/maplibre-gl.css" rel="stylesheet" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 
    <link href="https://fonts.googleapis.com/css2?family=Rampart+One&amp;display=swap" rel="stylesheet">
  </head>
  <body>loading...</body>
</html>
/* scss/style.scss */

body { margin: 0; padding: 0; }
html, body, body > div { height: 100%; }