DEV Community

Cover image for Geocode with OpenCage and MapLibre
Arnaud Ferrand
Arnaud Ferrand

Posted on • Updated on

Geocode with OpenCage and MapLibre

OpenCage is an API Provider offering two services a geocoding service and a geosearch service
MapLibre is an Open-source mapping libraries for web and mobile app developers.

In this article we will learn how to geocode with OpenCage and the maplibre-gl-geocoder plugin.

First, one need an OpenCage API Key, it is free for testing, signup for your own key here.

This example will be based on a simple HTML page.


The header will then contain a viewport:

<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
Enter fullscreen mode Exit fullscreen mode

Some CSS and JS for MapLibre and the geocoder plugin

<!-- STYLES -->
<link href="" rel="stylesheet" />
<link href="" rel="stylesheet" />
Enter fullscreen mode Exit fullscreen mode
<!-- scripts -->
<script src=""></script>
<script src=""></script>
Enter fullscreen mode Exit fullscreen mode
<!-- CSS -->
body {
  margin: 0;
  padding: 0;
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
Enter fullscreen mode Exit fullscreen mode


Now let's look at the body of this HTML page

<div id="map"></div>
Enter fullscreen mode Exit fullscreen mode

Pretty sleek, isn't it?



Indeed the magic happens in JS. The first part is the map using MapLibre GL JS. Here, I used a simple openstreetmap basemap using a raster source. The SDK offers various sources link.

var map = new maplibregl.Map({
  container: "map",
  // Use a minimalist raster style
  style: {
    version: 8,
    name: "Blank",
    center: [0, 0],
    zoom: 0,
    sources: {
      "raster-tiles": {
        type: "raster",
        tiles: ["{z}/{x}/{y}.png"],
        tileSize: 256,
        minzoom: 0,
        maxzoom: 19
    layers: [
        id: "background",
        type: "background",
        paint: {
          "background-color": "#e0dfdf"
        id: "simple-tiles",
        type: "raster",
        source: "raster-tiles"
    id: "blank"
  center: [0, 51],
  zoom: 4,
  antialias: true
Enter fullscreen mode Exit fullscreen mode


We define the geocoder API. From the documentation Any geocoder api that supports the functions reverseGeocode and forwardGeocode and returns a response which includes a FeatureCollection of results

We use the OpenCage API and its GeoJSON format, but as you can see, because this is JS, one can use the classical JSON response from the API and transform into GeoJSON.

// Replace it with your API Key. 
// The test key returns only 
// "Friedrich-Ebert-Straße 7, 48153 Münster, Germany" 
// whatever the input is
var YOUR_API_KEY="6d0e711d72d74daeb2b0bfd2a5cdfdba";

var geocoder_api = {
  forwardGeocode: async (config) => {
    const features = [];
    try {
      let request =
        "" +
        config.query +
      const response = await fetch(request);
      const geojson = await response.json();
      for (let feature of geojson.features) {
        let point = {
          type: "Feature",
          geometry: {
            type: "Point",
            coordinates: feature.geometry.coordinates
          place_type: ["place"]
    } catch (e) {
      console.error(`Failed to forwardGeocode with error: ${e}`);

    return {
      features: features
Enter fullscreen mode Exit fullscreen mode

now add the Geocoder API to the plugin and attached it to the map

  new MaplibreGeocoder(geocoder_api, {
    maplibregl: maplibregl
Enter fullscreen mode Exit fullscreen mode

and we are all set.


A live example using the test API key (returning only Münster) is available on codepen

The end

Thanks for reading 🙏


Top comments (0)