Use Maps from any Provider in React
By: Lucas Andión
Tags: JavaScript, Mapbox, Maps, Leaflet, React

Use Maps from any Provider in React

Photo by Annie Spratt on Unsplash

There are several libraries to create Map views on React, most of them target only one provider, as the popular google-map-react and google-maps-react libraries for Google Maps.

But what if you want to be able to start using Bing maps? Or use OpenStreetMap when your main provider is down, or you hit some request limit? You can always wrap your different providers on some abstraction over their corresponding libraries, but there’s a better choice.

Enter Leaflet

Leaflet it’s an awesome open-source map library developed by Vladimir Agafonkin. It supports a great variety of providers, really, a lot.

Some of the tile layers from supported providers. Full demo here.

Using Leaflet, with the same code you can easily swap which one you are using by changing your tile layer.

A tile layer is used to load and display map layers (or other data that can be geographically represented) from our provider of choice onto our Leaflet map component.

Most of the ones based in OpenStreetMap are free, and some require an API key and that you provide attribution. We’ll use MapBox in this example. It uses OpenStreetMap as a base, but in order to use it you must get an access_token here.

Creating our first map

To create your first map you will need an HTML file with Leaflet’s .css and .js files and a div with a specific id to attach your map to. Remember to set the width and height of the map container or it won’t work.

Then just add MapBox’s tileLayer to the map using your access_token and proper attribution .

We will be also adding a marker with a popup to the map. Here’s the full example:

Our first example

To place our marker we need to specify a place or geographical point on the map, in this case: towerLocation . It will point to the Tower of Hercules.

This point should be a LatLng object or equivalent. It can be as simple as an array of latitude and longitude coordinates, but in Leaflet they could be represented in any of these forms:

L.latLng([43.385807,-8.406524]); {lon: -8.406524, lat: 43.385807}; {lat: 43.385807, lng: -8.406524}; [43.385807,-8.406524]; // Our preferred

Using towerLocation as the map’s center the result in your browser will look like this.

Looks great, right?

Using Leaflet in React

I know I know… I said React, not vanilla JS. To work with Leaflet on a more React friendly way we will be using React-Leaflet.

It provides an abstraction of Leaflet as React components. It does not replace Leaflet, only leverages React’s lifecycle methods to call the relevant Leaflet handlers.

To use it on your project you’ll need to:

Install leaflet and react-leaflet:

yarn add leaflet react-leaflet or npm install leaflet react-leaflet Use leaflet’s CSS, otherwise you’ll see the map with its tiles oddly distributed:

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" /> As with the previous example set at least the height of the map’s container. In this case react-leaflet creates its own container, so you can style its CSS class like this:

.leaflet-container {

width: 800px;

height: 600px;

}

With all this in place our previous example would be this component:

Not so configurable right now, but you get the idea. This will look exactly as the previous image.

Rendering the same map using different providers

If we wanted to show our maps also using OpenStreetMap or HERE, we can just use the same <MyMap /> component, passing different map parameters (URL template and attribution) as props.

URL templates for each map type can be found on the list of providers or each provider’s page. They contain placeholder variables inside brackets that Leaflet will update or set defaults for.

{s} means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; a , b or c by default, can be omitted), {z} — zoom level, {x} and {y} — tile coordinates. {r} can be used to add "@2x" to the URL to load retina tiles. You can use custom keys in the template, which will be evaluated from TileLayer options.

Leaflet will update {x} , {y} and {z} accordingly and set defaults for the rest. We’ll use a custom key to set our tokens so we’ll need to update our MyMap component to pass any extra key to <TileLayer /> . Our final code will look something like this:

Our final example.

If you update the CSS to show all the maps you may have this result, with four different layers from four different providers.

Note HERE also requires an api key (and doesn’t even use OpenStreetMap maps as the rest)

As a bonus, Leaflet maps are mobile-friendly so just changing the container size to this on any of the maps:

.leaflet-container {

width: 100vw;

height: 100vh;

}

Will create a full size map view on your phone that runs smoothly.

It really feels like snappy on mobile.

Going further

With React-Leaflet you can not only use almost any provider’s maps, but print tooltips, markers, layers, paths or shapes on it.

You can also combine different layers from various providers, such as weather information, Maritime Routes, or railroads.

Leaflet is meant to be as lightweight as possible and has hundreds of plugins that provide more functionality. The problem is that not many of them are ported to React-Leaflet (v2), so sometimes you’ll need to create your own react-leaflet components. The good part is it’s not that hard.