JavaScript drop-ins for map and geocoder libraries

Front-end code is where a provider change hurts most, because the map library, the geocoder widget and the billing are tangled together. These loaders and settings let you keep the library code you have. Behind it, tiles, geocoding, autocomplete and elevation come from us. Map loads and tiles are free; only geocoding calls count toward your quota.

On this page

Google Maps JavaScript API

Load the maps library from gapi.mygeocode.com instead of maps.googleapis.com. The google.maps namespace is provided, with map tiles, markers, the Geocoder, Places Autocomplete and the ElevationService served by us. Map loads do not count toward your quota.

Before
<script async defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_KEY&libraries=places&callback=initMap">
</script>
After
<script async defer
  src="https://gapi.mygeocode.com/maps/api/js?key=YOUR_MYGEOCODE_KEY&libraries=places&callback=initMap">
</script>
Then use it as before
// Nothing below this line changes.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 51.5074, lng: -0.1278 },
    zoom: 12
  });

  const geocoder = new google.maps.Geocoder();
  geocoder.geocode({ address: "221B Baker Street, London" }, (results, status) => {
    if (status === "OK") {
      map.setCenter(results[0].geometry.location);
      new google.maps.Marker({ map, position: results[0].geometry.location });
    }
  });

  const input = document.getElementById("search");
  const autocomplete = new google.maps.places.Autocomplete(input, { fields: ["geometry", "formatted_address"] });
  autocomplete.addListener("place_changed", () => {
    const place = autocomplete.getPlace();
    if (place.geometry) map.panTo(place.geometry.location);
  });
}

Included

  • google.maps.Map with our tiles (roadmap, satellite and terrain map types)
  • Marker, InfoWindow, Polyline, Polygon, Circle, Rectangle, LatLng, LatLngBounds, event
  • Geocoder (forward and reverse)
  • places.Autocomplete widget and places.AutocompleteService
  • ElevationService
  • Controls, gestures, styled maps with the same style array format

Not included

  • Street View
  • Directions, Distance Matrix and Routes
  • Places Details, Photos and Nearby Search
  • Drawing, Visualization and Geometry libraries
  • 3D and WebGL overlay views

What counts as a request. Map loads and tile requests are free. Each Geocoder call, each Autocomplete session and each ElevationService call counts as one request.

Bing Maps V8 Web Control

The V8 control is retired along with the rest of Bing Maps for Enterprise. Load the control from bing.mygeocode.com and the Microsoft.Maps namespace keeps working, with our tiles, geocoding and autosuggest behind it.

Before
<script async defer
  src="https://www.bing.com/api/maps/mapcontrol?key=YOUR_BING_KEY&callback=loadMap">
</script>
After
<script async defer
  src="https://bing.mygeocode.com/api/maps/mapcontrol?key=YOUR_MYGEOCODE_KEY&callback=loadMap">
</script>
Then use it as before
function loadMap() {
  const map = new Microsoft.Maps.Map("#map", { center: new Microsoft.Maps.Location(47.6396, -122.13), zoom: 12 });

  Microsoft.Maps.loadModule("Microsoft.Maps.Search", () => {
    const search = new Microsoft.Maps.Search.SearchManager(map);
    search.geocode({
      where: "1 Microsoft Way, Redmond, WA",
      callback: (result) => {
        const loc = result.results[0].location;
        map.setView({ center: loc, zoom: 15 });
        map.entities.push(new Microsoft.Maps.Pushpin(loc));
      }
    });
  });
}

Included

  • Microsoft.Maps.Map, Location, LocationRect, Pushpin, Infobox, Polyline, Polygon, Layer
  • Search module: SearchManager.geocode and reverseGeocode
  • Autosuggest module: AutosuggestManager and the input attachment
  • Road, aerial and grayscale map types with our tiles
  • Events, navigation bar and map options

Not included

  • Directions module
  • Traffic, Spatial Data Services and Spatial Math advanced functions
  • Bird's eye and Streetside imagery
  • Well Known Text, GeoJSON and GeoXml modules (use the GeoJSON module from Leaflet or MapLibre instead)

What counts as a request. Map loads and tiles are free. Each geocode, reverseGeocode and each autosuggest session counts as one request.

Mapbox GL JS and mapbox-gl-geocoder

Keep your map code and swap the two URLs: the style, and the geocoder origin. MapLibre GL JS (the open source fork) is the recommended renderer; Mapbox GL JS v1 also works. mapbox-gl-geocoder has an origin option, so the geocoder control needs no code changes beyond that.

Before
const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/mapbox/streets-v12",
  accessToken: "YOUR_MAPBOX_TOKEN"
});
map.addControl(new MapboxGeocoder({
  accessToken: "YOUR_MAPBOX_TOKEN",
  mapboxgl: mapboxgl
}));
After
const map = new maplibregl.Map({
  container: "map",
  style: "https://mapbox.mygeocode.com/styles/v1/mygeocode/streets?access_token=YOUR_MYGEOCODE_KEY"
});
map.addControl(new MapboxGeocoder({
  accessToken: "YOUR_MYGEOCODE_KEY",
  origin: "https://mapbox.mygeocode.com",
  mapboxgl: maplibregl
}));
Then use it as before
// Direct calls keep the same shape too
const res = await fetch(
  "https://mapbox.mygeocode.com/geocoding/v5/mapbox.places/Oxford%20Street%20London.json?access_token=YOUR_MYGEOCODE_KEY"
);
const { features } = await res.json();
map.flyTo({ center: features[0].center, zoom: 15 });

Included

  • Vector tile styles: streets, light, dark and outdoors, in the Mapbox style specification
  • mapbox-gl-geocoder with the origin option, including proximity, bbox, countries and types
  • Static images at /styles/v1/mygeocode/{style}/static/{lon},{lat},{zoom}/{width}x{height}
  • Raster tiles at /v4/mygeocode.streets/{z}/{x}/{y}.png for Leaflet and OpenLayers

Not included

  • Mapbox GL JS v2 and later (its licence requires Mapbox tokens; use MapLibre)
  • Directions, Isochrone, Matrix and Optimization APIs
  • Mapbox Studio custom styles (upload your style JSON to your account instead)

What counts as a request. Tiles and static images are free. Each geocoder request counts as one request; the autocomplete keystrokes are debounced by the control as usual.

Leaflet geocoder plugins

Leaflet talks to geocoders through plugins, and the popular ones accept a service URL. Point Leaflet Control Geocoder or leaflet-geosearch at osm.mygeocode.com and use our tiles for the base map.

Before
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
  attribution: "&copy; OpenStreetMap contributors"
}).addTo(map);

L.Control.geocoder({
  geocoder: L.Control.Geocoder.nominatim()
}).addTo(map);
After
L.tileLayer("https://tiles.mygeocode.com/streets/{z}/{x}/{y}.png?key=YOUR_MYGEOCODE_KEY", {
  attribution: "&copy; My Geocode"
}).addTo(map);

L.Control.geocoder({
  geocoder: L.Control.Geocoder.nominatim({
    serviceUrl: "https://osm.mygeocode.com/",
    geocodingQueryParams: { key: "YOUR_MYGEOCODE_KEY" }
  })
}).addTo(map);
Then use it as before
// leaflet-geosearch works the same way
import { OpenStreetMapProvider, GeoSearchControl } from "leaflet-geosearch";

const provider = new OpenStreetMapProvider({
  searchUrl: "https://osm.mygeocode.com/search",
  reverseUrl: "https://osm.mygeocode.com/reverse",
  params: { key: "YOUR_MYGEOCODE_KEY", addressdetails: 1 }
});
map.addControl(new GeoSearchControl({ provider, style: "bar" }));

Included

  • Leaflet Control Geocoder: nominatim, google, bing, mapbox, here, opencage, latLng and mapquest geocoders, each pointed at the matching mygeocode.com host
  • leaflet-geosearch: OpenStreetMapProvider, GoogleProvider, BingProvider, HereProvider, LocationIQProvider, OpenCageProvider, GeoapifyProvider
  • Raster tiles in streets, light and dark styles
  • Any other plugin that lets you set the Nominatim URL

Not included

  • Routing plugins (Leaflet Routing Machine and similar)
  • Tile styles beyond the three listed

What counts as a request. Tiles are free. Each geocode and each reverse geocode counts as one request.

HERE Maps API for JavaScript

Load the mapsjs bundles from here.mygeocode.com and create the platform as usual. H.Map, H.service.Platform and the search service keep their signatures, with vector tiles and geocoding from us.

Before
<script src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
After
<script src="https://here.mygeocode.com/v3/3.1/mapsjs-core.js"></script>
<script src="https://here.mygeocode.com/v3/3.1/mapsjs-service.js"></script>
<script src="https://here.mygeocode.com/v3/3.1/mapsjs-ui.js"></script>
<script src="https://here.mygeocode.com/v3/3.1/mapsjs-mapevents.js"></script>
Then use it as before
const platform = new H.service.Platform({ apikey: "YOUR_MYGEOCODE_KEY" });
const layers = platform.createDefaultLayers();
const map = new H.Map(document.getElementById("map"), layers.vector.normal.map, {
  center: { lat: 52.5304, lng: 13.3853 }, zoom: 13
});

platform.getSearchService().geocode(
  { q: "Invalidenstraße 116, Berlin" },
  (result) => {
    const { position } = result.items[0];
    map.setCenter(position);
    map.addObject(new H.map.Marker(position));
  },
  (err) => console.error(err)
);

Included

  • H.Map, H.map.Marker, H.map.Polyline, H.map.Polygon, H.map.Group
  • H.service.Platform with createDefaultLayers (vector normal, satellite, terrain)
  • SearchService: geocode, reverseGeocode, autosuggest
  • H.ui.UI default controls and H.mapevents.Behavior
  • H.geo.Point, H.geo.Rect and helpers

Not included

  • Routing, Isoline and Public Transit services
  • Traffic and incident layers
  • Places Discover and Browse
  • Custom map styles from HERE Style Editor (use our style JSON format)

What counts as a request. Map loads and tiles are free. Each geocode, reverseGeocode and autosuggest call counts as one request.

MapQuest.js

MapQuest.js wraps Leaflet and adds L.mapquest.geocoding(). Load the bundle from mapquest.mygeocode.com and set your key as before.

Before
<script src="https://api.mqcdn.com/sdk/mapquest-js/v1.3.2/mapquest.js"></script>
<link type="text/css" rel="stylesheet" href="https://api.mqcdn.com/sdk/mapquest-js/v1.3.2/mapquest.css"/>
After
<script src="https://mapquest.mygeocode.com/sdk/mapquest-js/v1.3.2/mapquest.js"></script>
<link type="text/css" rel="stylesheet" href="https://mapquest.mygeocode.com/sdk/mapquest-js/v1.3.2/mapquest.css"/>
Then use it as before
L.mapquest.key = "YOUR_MYGEOCODE_KEY";

const map = L.mapquest.map("map", {
  center: [41.8789, -87.6359],
  layers: L.mapquest.tileLayer("map"),
  zoom: 12
});

L.mapquest.geocoding().geocode("233 S Wacker Dr, Chicago, IL", (err, response) => {
  const loc = response.results[0].locations[0].latLng;
  map.setView(loc, 15);
  L.marker(loc, { icon: L.mapquest.icons.marker() }).addTo(map);
});

Included

  • L.mapquest.map, tileLayer (map, hybrid, satellite, light, dark)
  • L.mapquest.geocoding with geocode and reverse
  • L.mapquest.searchAhead (autocomplete) control
  • Icons, control positions and the standard Leaflet API

Not included

  • Directions and route layers
  • Traffic layer
  • Static Map API

What counts as a request. Tiles are free. Each geocode, reverse and search-ahead request counts as one request.

Map tiles and styles

Every loader above uses the same tile service, which you can also use directly from any library.

FormatURL
Raster, 256pxhttps://tiles.mygeocode.com/{style}/{z}/{x}/{y}.png
Raster, 512px for high density screenshttps://tiles.mygeocode.com/{style}/{z}/{x}/{y}@2x.png
Vector tiles (MVT)https://tiles.mygeocode.com/v/{z}/{x}/{y}.pbf
Style JSON for MapLibre and Mapbox GLhttps://tiles.mygeocode.com/styles/{style}.json

Styles are streets, light, dark, outdoors and satellite. Add ?key=... to attach tile traffic to your account if you want it in your dashboard; it is not billed either way. Our tiles are rendered from OpenStreetMap data and our own; the attribution control must show © OpenStreetMap contributors and My Geocode, which the loaders above add for you.

Keys in the browser

Do not put an account API key in client-side code. Keys are limited to two IP addresses in any 24 hour period, so the third visitor would be refused, and a key in page source is a key anyone can read.

For pages served to the public, use one of these instead:

  • No key. Each visitor's browser uses the free 2,500 requests a day from their own IP address. For most sites this is enough, and it costs you nothing. The YOUR_MYGEOCODE_KEY placeholders above can simply be left empty.
  • Your own proxy. Route geocoding calls through your server, which uses a normal key or a whitelisted IP. The map loaders accept a proxy parameter for this: gapi.mygeocode.com/maps/api/js?proxy=https://yoursite.com/geo.