82

I'm trying to use react-leaflet to display a map. I use the code from this fiddle which is working, but on my computer I have this output

enter image description here

Here is my code :

DeviceMap.js

import React from 'react'
import { Map, Marker, Popup, TileLayer } from 'react-leaflet';

export class DeviceMap extends React.Component {
  constructor() {
    super();
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    };
  }

  render() {
    const position = [this.state.lat, this.state.lng];
    return (
      <Map center={position} zoom={this.state.zoom} scrollWheelZoom={false}>
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
        />
        <Marker position={position}>
          <Popup>
            <span>A pretty CSS3 popup. <br/> Easily customizable.</span>
          </Popup>
        </Marker>
      </Map>
    );
  }
}

export default DeviceMap

DeviceTabs.js

export class DeviceTabs extends React.Component {
  state = {
    index: 0
  };

  handleTabChange = (index) => {
    this.setState({ index })
  };

  render () {
    return (
      <Tabs index={this.state.index} onChange={this.handleTabChange}>
        <Tab label='Values'>
          <DeviceTable {...this.props} />
        </Tab>
        <Tab label='Map'>
          <div className={style.leaflet}>
            <DeviceMap />
          </div>
        </Tab>
      </Tabs>
    )
  }
}

style.scss

.leaflet {
  height: 300px;
  width: 100%;
}

There is no error in the console, and I have no more idea where to search. Since the fiddle is working it is not a bug. Did I miss something ?

Michael Ramos
  • 5,523
  • 8
  • 36
  • 51
ThomasThiebaud
  • 11,331
  • 6
  • 54
  • 77

18 Answers18

121

Looks like you haven't loaded in the Leaflet stylesheet.

From the react-leaflet GitHub guide:

If you are not familiar with Leaflet, make sure you read its quick start guide before using this library. You will notably need to add its CSS to your page to render the map properly, and set the height of the container.

http://leafletjs.com/examples/quick-start/

Here is what you'll need:

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />

Update

Note @ThomasThiebaud indicates you may also have to set up the height of .leaflet-container

--

Ange Loron also gave a correct, optional, JS module import (vs cdn or style link)

import 'leaflet/dist/leaflet.css';



For what its worth, the documentation page is poorly designed... and the maintainer continuously deals with this issue in GitHub, but for some reason, the issue is the *fault of the users who continuously don't do the required setup. /s

Michael Ramos
  • 5,523
  • 8
  • 36
  • 51
  • 2
    Thanks for your answer. With this line I loose everything (no error, nothing displayed). I think there is another problem with the height of the map because I'm using css modules. I will investigate tomorrow. – ThomasThiebaud Nov 01 '16 at 20:13
  • @ThomasThiebaud sounds good, also want to make sure your leaflet version matches up with the link I provided, and to set height of map component/container. – Michael Ramos Nov 01 '16 at 22:27
  • The problem remains the same. I try with `react-leaflet@0.12.3` and `leafflet@0.7.7` and also with `react-leaflet@1.0.0-rc.2` and `leafflet@1.0.1`. I also fix the height of my component using `
    ` with `#map { height: 300px }`
    – ThomasThiebaud Nov 02 '16 at 08:30
  • 25
    I got it ! You have to setup the height of `.leaflet-container` also – ThomasThiebaud Nov 02 '16 at 08:59
  • 8
    Funny how stackoverflow answers sometimes provide better information than official docs. – Konrad Jul 09 '20 at 10:18
  • 5
    you are a beautiful person. this comment saved my project – Gibs LeFleur Aug 18 '20 at 01:47
  • import 'leaflet/dist/leaflet.css' import Leaflet from 'leaflet' import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png' import iconUrl from 'leaflet/dist/images/marker-icon.png' import shadowUrl from 'leaflet/dist/images/marker-shadow.png' import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet' Leaflet.Icon.Default.imagePath = '../node_modules/leaflet' delete Leaflet.Icon.Default.prototype._getIconUrl Leaflet.Icon.Default.mergeOptions({ iconRetinaUrl, iconUrl, shadowUrl, }) – coderfin Jul 31 '21 at 03:48
  • `import 'leaflet/dist/leaflet.css'` doesn't "just work" because the CSS has references to image files located in the dist folder. The project owner needs to document how this should be setup properly. – rm.rf.etc Nov 04 '21 at 21:57
  • for me I had to give the map container component some style height and width and it then started showing up :| ...but the react-leaflet docs tell anything about...the leaflet docs does... – siddharthrc Apr 02 '23 at 00:57
62

I am also new to using this library and didn't find the documentation clear enough. But here are few things I find necessary in order for this to work.

1. react-leaflet package

2. Leaflet package:

Either, install it using npm

npm install leaflet and
import 'leaflet/dist/leaflet.css'; in the file where you use Map from react-leaf.

OR

Include these two lines in the index.html:

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

<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
  integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
  crossorigin=""></script>

3. Add this to a App.css or index.css and import the file: (And its a must)

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

// OR add style directly to the map container

<Map
   center={position}
   zoom={1}
   style={{ height: '100vh', width: '100wh' }}
   >
   <TileLayer .... />
</Map>

Bikram Karki
  • 985
  • 8
  • 8
30

Just in case someone runs into the same issue, I solved it by simply adding this:

import 'leaflet/dist/leaflet.css';
Ange Loron
  • 1,093
  • 1
  • 11
  • 23
17

Try this

import React, { Component } from 'react'
import Leaflet from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet'
import 'leaflet/dist/leaflet.css';

Leaflet.Icon.Default.imagePath =
'../node_modules/leaflet'

delete Leaflet.Icon.Default.prototype._getIconUrl;

Leaflet.Icon.Default.mergeOptions({
    iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
    iconUrl: require('leaflet/dist/images/marker-icon.png'),
    shadowUrl: require('leaflet/dist/images/marker-shadow.png')
});



export default class MapDisplay extends Component {
state = {
    lat: 41.257017,
    lng: 29.077524,
    zoom: 13,
}


render() {
    const position = [this.state.lat, this.state.lng]
    return (
    <Map center={position} zoom={this.state.zoom} style={{height : '400px'}}>
        <TileLayer
        attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <Marker position={position}>
        <Popup>
            Son Konum
        </Popup>
        </Marker>
    </Map>
    )
}
}
Cem Karakurt
  • 241
  • 3
  • 5
14

You should just add this to your CSS File, i had the same problem as you and this method fixed my problem :

  @import url("~leaflet/dist/leaflet.css");

.leaflet-container {
  width: 100%;
  height: 100vh;
}
Chris Lopez
  • 271
  • 1
  • 3
  • 11
12

You can fix by adding the following lines of code inside head element on your index.html.

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css">

<style>
  body {
    padding-bottom: 30px;
  }
  h1, h2, p {
    font-family: sans-serif;
    text-align: center;
  }
  .leaflet-container {
    height: 400px;
    width: 80%;
    margin: 0 auto;
  }
</style>

Note: You can change the CSS to meet your needs.

habib
  • 2,366
  • 5
  • 25
  • 41
edgar mlowe
  • 161
  • 1
  • 8
9

import leaflet.css

import 'leaflet/dist/leaflet.css';

some times there are two errors about the image loading after adding the leaflet file. for resolving these errors, import marker-icon.png and marker-shadow.png in the import part and then define the L.Marker.prototype.options.icon:

import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
import iconRetina from 'leaflet/dist/images/marker-icon-2x.png';
let DefaultIcon = L.icon({
            ...L.Icon.Default.prototype.options,
            iconUrl: icon,
            iconRetinaUrl: iconRetina,
            shadowUrl: iconShadow
        });
        L.Marker.prototype.options.icon = DefaultIcon;

if the map doesn't show, add the height and width(style={{width: '100%',height: '400px'}}) to Map tag as a style:

<Map
center={[35.6892, 51.3890]}
style={{width: '100%',height: '400px'}}
>

Add height and width

Tetraib
  • 13
  • 6
Mohammad
  • 537
  • 9
  • 6
8

In my case with React adding this helped:

<MapContainer
        center={{ lat: 51.505, lng: -0.09 }}
        zoom={13}
        style={{ height: "50vh", width: "100%" }}
        scrollWheelZoom={false}
      >

It needs to be at least 1 parameter height or width with vh, otherwise if you use only 100%/100% wont work

Hvitis
  • 502
  • 5
  • 14
4

if someone was looking for how to embed this into a separate component, I figured out how to do that after some struggles

import React from 'react';
import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet";
import './MapObject.css'

const position = [51.505, -0.09]
class MapObject extends React.Component {
    render() {

        return (
                <MapContainer center={position} zoom={13} scrollWheelZoom={false}>
                <TileLayer
                attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                <Marker position={position}>
                <Popup>
                    A pretty CSS3 popup. <br /> Easily customizable.
                </Popup>
                </Marker>
            </MapContainer>           
        );
    }
}

This is then simply loaded by

import MapObject from './MapObject'

And the MapObject.css needs to look like this (without this it doesn't appear at all)

.leaflet-container {
    width: 100%;
    height: 100vh;
  }

Resulting map is here:

enter image description here

DovaX
  • 958
  • 11
  • 16
3
**Go to your react app folder my-app/public/index.html open index.html

and pest this two links in head tag
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>

</head>**



<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css">
    <style>
    #mpp {

            overflow: hidden;
        }
    </style>
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#000000" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>
JHM16
  • 649
  • 8
  • 12
2

this solved my issue:

adding this to the index.html

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css">

<style>
  .leaflet-container {
   height: 400px;
   width: 800px;
 }
</style>

source: https://medium.com/@eugenebelkovich/map-for-react-apps-with-leaflet-365f9df82d55

1

If non of these work for you you can try to manually resize the window when the page loads.

window.dispatchEvent(new Event('resize'));
1

I don't know why, Adding Leaflet css file is not enough...

It seems you also have to add:

.leaflet-container{
  height:500px;
}
1

For this case, according to the search I did, I came to the conclusion that first the width of the part I am working on should be set. On the other hand, after that, I had access to the DOM map. I added a delay of 100 milliseconds, after which the initial setting I do the map.

1

just add the leaflet style from any cdn similar to your version

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" />
Hisham Shami
  • 439
  • 4
  • 8
0

try this :

 var mapid = $(this).find('[id^=leaflet-map]').attr('id');
      var map = settings.leaflet[mapid].lMap;
      map.invalidateSize();
Matoeil
  • 6,851
  • 11
  • 54
  • 77
0

In Leaflet Map, if your map is not showing properly this problem is due to CSS file.

Try this CSS in your public/index.html

<link href='https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.css' rel='stylesheet'>
Erica
  • 2,399
  • 5
  • 26
  • 34
0

My map was totally not being displayed even after setting the height and css. You need to add the following leaflet cdn and css to your index.html file for it to work:

<link rel="stylesheet" 
href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css">    
<style>
     .leaflet-container {
       height: 500px;
       width: 960px;
     }    </style>

    <!-- Make sure you put this AFTER Leaflet's CSS -->
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
      integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
      crossorigin=""></script>
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
briancoder
  • 159
  • 1
  • 9