React map libraries overview + react-leaflet complete installation debugging guide
Tags: react, beginners, opensource, webdev
Published: 2022-07-28 20:44:00

While I was looking for some good map libraries for React, [react-leaflet](https://react-leaflet.js.org/) caught my eye. 
[react-leaflet](https://react-leaflet.js.org/) is a react library that is a complete rewrite of [leaflet](https://leafletjs.com/), which is an open-source JavaScript library for mobile-friendly interactive maps.

## React Map Libraries
Besides react-leaflet, I had a few other options. Why did I not opt to use these libraries?

1. [React Simple Maps](https://www.react-simple-maps.io/)
Great library in general. It is very easy to use and has decent documentation with some examples as well. Also as the name goes, it is very lightweight. However, it did not suit my purpose of needing to display precise locations with markers. Yes, it is possible to do so by using React Simple Maps, but I would need to redesign the whole map template which was not worth putting in my effort and time while there are already existing libraries that have maps with great default templates.

1. [React Mapbox GL](https://github.com/alex3165/react-mapbox-gl)
A decent library, but not recommended. The original library of [Mapbox](https://docs.mapbox.com/) is well made with great examples, but the rewrite for React is not well maintained. It barely has any examples, and there are not that much resource online. The documentation is not adequate as well. Unless you're an advanced, skilled developer, not the best option.

1. [React Google Maps](https://www.npmjs.com/package/@react-google-maps/api)
Seemed to be great. However, I haven't had the chance to really feel it out since activating the API key requires subscription. If you could afford the subscription, definitely go for it!

## Why react-leaflet?
I wouldn't say react-leaflet is the most robust library compared to its competitors (i.e. react google maps). However, it has little of everything, and that was enough to serve my purpose.

- Good map template. By template I mean the actual map design. I needed a map with precise street annotations with good color scheme. I would say it is subpar to Google Maps API or Mapbox GL when it comes to the actual design, but it did the job.

- Good documentation with good examples. Honestly speaking, the documentation is not the best, but it was decent enough to get away with. The existing examples did lack explanation, but the code itself was pretty easy to understand even at first glance. Even though the quality of the documentation and examples were not paramount, since my second-most compelling option, react mapbox gl, was far behind when it came to examples, I had to choose react-leaflet.

## Installation

Unfortunately, even with its pros, react-leaflet does not have the best documentation for beginners. Even from the installation and the map setup, there are a lot that are not mentioned in the documentation. So I thought I would provide a installation debugging guide for potential problems/glitches.

**Installation**
If you have the time, read through the [installation page](https://react-leaflet.js.org/docs/start-installation/), but if not, just run these commands on the terminal. If you don't even have a react app, start a react app first.

```
npm install leaflet
******install react-leaflet after installing leaflet******
npm install react-leaflet
```

After installing these modules, import the basic components.

```js
import { MapContainer, TileLayer, useMap } from 'react-leaflet'
```
**Setup**
Copy paste the following code in your react app to render a simple map with a marker.

```js
<MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={false}>
  <TileLayer
    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
  />
  <Marker position={[51.505, -0.09]}>
    <Popup>
      A pretty CSS3 popup. <br /> Easily customizable.
    </Popup>
  </Marker>
</MapContainer>
```
If it worked fine for you, great! 
But if you're running into any of these problems, read through the debugging guide down below.

## Debugging Guide

**Module Error**
If you're getting an error like below, do not worry!

```
 ./node_modules/@react-leaflet/core/esm/path.js 10:41
Module parse failed: Unexpected token (10:41)
File was processed with these loaders:
 * ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|   useEffect(function updatePathOptions() {
|     if (props.pathOptions !== optionsRef.current) {
>       const options = props.pathOptions ?? {};
|       element.instance.setStyle(options);
|       optionsRef.current = options;
```
Here's a solution.
Open your `package.json` and change

```json
 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},
```
to

```json
"browserslist": [
   ">0.2%",
  "not dead",
  "not op_mini all"
],
```
**Map Not Rendering Properly**

- Solution 1

Add the following line to your code.

```js
import 'leaflet/dist/leaflet.css';
```
Not working? Solution 2 should work!

- Solution 2

Navigate to your `index.html`.
In the `<header>`, add the following code.

```html
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
  integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
  crossorigin=""/>

<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
  integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
  crossorigin=""></script>
```
Add the following code to `App.css`.

```css
.leaflet-container {
  width: 100wh; 
  height: 100vh;
}
```

If anyone runs into any other problems in the installation step, I will be willing to help. Please drop down your problem in the comments section. Happy debugging!