Use USGS Topo Tiles with Leaflet

Display our USGS topographic tiles in a map using the Leaflet JavaScript library.

Topo Map Tiles

Once you have obtained your access token, you may now request map tiles from our mapping microservices.

Leaflet is a popular JavaScript library used to create interactive maps for the web. Because our USGS topographic tiles microservice requires an access token, you will need to extend Leaflet's default functionality to pass the access token with every tile request. This article will describe an example implementation that achieves this functionality.

Assuming you have an HTML div with an ID of "map", start by creating a Leaflet map instance.

// Create a map instance and set the view parameters
var map ="map").setView([51.505, -0.09], 13);

We offer two methods of authenticating with USGS Topo Tiles: OAuth and API key. Examples of both methods are presented below.


When using an API key, simply add a TMS tile layer with the API key passed as a query parameter in the URL.

const key = "[API Key]";
L.tileLayer(`{z}/{x}/{y}.png?x-api-key=${key}`, {
    tms: true


Create a custom Leaflet GridLayer that correctly requests a tile and displays it on a map grid in the form of an HTML img.

L.GridLayer.TopoLayer = L.GridLayer.extend({
  createTile: function ({ x, y, z }) {
    const tile = document.createElement("img");
    const token = "[Access token]";
    // Convert from WMS to TMS by inverting the Y parameter
    const invertedY = this._globalTileRange.max.y - y;
    // Build the tile URL
    const tileUrl = `${z}/${x}/${invertedY}.png`;
    fetch(tileUrl, {
      method: "GET",
      withCredentials: true,
      headers: {
        Authorization: `Bearer ${token}`,
      .then((res) => {
        // Return the response as an ArrayBuffer
        return res.arrayBuffer();
      .then((data) => {
        // Convert the binary data returned from the API to a base64-encoded string
        const tileData = btoa(
          new Uint8Array(data).reduce(
            (d, byte) => d + String.fromCharCode(byte),
        // Set the tile element's source to the base64-encoded string
        tile.src = "data:;base64," + tileData;
      .catch((err) => {
        // Log any errors
        console.log("Something went wrong!", err);
    return tile;

Finally, wrap the custom GridLayer in a function and add an instance of this to the map.

// Create a wrapper function around the custom GridLayer
L.gridLayer.topoLayer = function (opts) {
  return new L.GridLayer.TopoLayer(opts);
// Create an instance of the custom GridLayer and add it to the map
const instance = L.gridLayer.topoLayer({
  maxNativeZoom: 15,
  minZoom: 0,
  maxZoom: 20,


Clockwork Micro is based in Seattle and Paris.



Copyright2024Clockwork Micro. All rights reserved.

Clockwork Micro