Preview:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>OS Maps API | Basic Map ZXY (EPSG:3857) | Leaflet</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/OrdnanceSurvey/os-api-branding@0.3.1/os-api-branding.css" />
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-omnivore/0.3.4/leaflet-omnivore.min.js"></script>
    <style>
        body, html { height: 100%; margin:0; padding:0; }
        
        #container {
            display: flex;
            flex-direction: column;
            height: 100%;
        }

        #map {
            flex-grow: 1;
        }

        #os-link-button {
            background-color: purple;
            color: white;
            text-align: center;
            padding: 15px 0;
            font-size: 16px;
            border: none;
            cursor: pointer;
            text-decoration: none;
        }
    </style>
</head>
<body>

<div id="container">
    <div id="map"></div>
    <a href="https://explore.osmaps.com/route/9146189/ashby-canal--hinckley-to-sutton-cheney-wharf?lat=52.561037&lon=-1.426466&zoom=12.9065&style=Leisure&type=2d" id="os-link-button">View this route in OS Maps</a>
</div>

<script src="https://cdn.jsdelivr.net/gh/OrdnanceSurvey/os-api-branding@0.3.1/os-api-branding.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
    const apiKey = '[key to go here]';

    const mapOptions = {
        minZoom: 7,
        maxZoom: 20,
        center: [54.425, -2.968],
        zoom: 14,
        maxBounds: [
            [49.528423, -10.76418],
            [61.331151, 1.9134116]
        ],
        attributionControl: false
    };

    const map = L.map('map', mapOptions);

    const basemap = L.tileLayer('https://api.os.uk/maps/raster/v1/zxy/Outdoor_3857/{z}/{x}/{y}.png?key=' + apiKey, {
        maxZoom: 20
    }).addTo(map);

    var firstWaypoint = true;
    var lastLatLng;

    var customLayer = L.geoJson(null, {
        pointToLayer: function(feature, latlng) {
            lastLatLng = latlng;
            if (firstWaypoint) {
                firstWaypoint = false;
                return L.marker(latlng);
            }
            return null;
        }
    });

    omnivore.gpx('route2.gpx', null, customLayer).on('ready', function() {
        map.fitBounds(this.getBounds());
        L.marker(lastLatLng).addTo(map);
    }).addTo(map);
</script>

</body>
</html>
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter