53
votes

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 ?

16

16 Answers

78
votes

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/[email protected]/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

25
votes

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

import 'leaflet/dist/leaflet.css';
25
votes

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/[email protected]/dist/leaflet.css"
  integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
  crossorigin=""/>

<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/[email protected]/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>

15
votes

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>
    )
}
}
11
votes

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.

8
votes

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

7
votes

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

4
votes

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;
}
3
votes
**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/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/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>
3
votes

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

1
votes

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
votes

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

It seems you also have to add:

.leaflet-container{
  height:500px;
}
0
votes

try this :

 var mapid = $(this).find('[id^=leaflet-map]').attr('id');
      var map = settings.leaflet[mapid].lMap;
      map.invalidateSize();
0
votes

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'>
0
votes

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

window.dispatchEvent(new Event('resize'));
0
votes

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/[email protected]/dist/leaflet.js"
      integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
      crossorigin=""></script>
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />