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 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 satellite map 🌐 🔗

Display a satellite raster baselayer.

Display a non-interactive map 🌐 🔗

Create a map without interactivity.

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.12.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.12.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.12.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.12.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.12.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.12.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 🔗

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.12.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.12.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.12.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.12.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.12.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.12.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.12.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@^5.12.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%; }