react-leaflet map not correctly displayed

JavascriptCssReactjsLeafletReact Leaflet

Javascript Problem Overview


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 ?

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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>

Solution 3 - Javascript

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

import 'leaflet/dist/leaflet.css';

Solution 4 - Javascript

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

Solution 5 - Javascript

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.

Solution 6 - Javascript

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;
}

Solution 7 - Javascript

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

Solution 8 - Javascript

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

Solution 9 - Javascript

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

Solution 10 - Javascript

**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>

Solution 11 - Javascript

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

Solution 12 - Javascript

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

It seems you also have to add:

.leaflet-container{
  height:500px;
}

Solution 13 - Javascript

try this :

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

Solution 14 - Javascript

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

Solution 15 - Javascript

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

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

Solution 16 - Javascript

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" />

Solution 17 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThomasThiebaudView Question on Stackoverflow
Solution 1 - JavascriptrambossaView Answer on Stackoverflow
Solution 2 - JavascriptBikram KarkiView Answer on Stackoverflow
Solution 3 - JavascriptAnge LoronView Answer on Stackoverflow
Solution 4 - JavascriptCem KarakurtView Answer on Stackoverflow
Solution 5 - Javascriptedgar mloweView Answer on Stackoverflow
Solution 6 - JavascriptChris LopezView Answer on Stackoverflow
Solution 7 - JavascriptMohammadView Answer on Stackoverflow
Solution 8 - JavascriptHvitisView Answer on Stackoverflow
Solution 9 - JavascriptDovaXView Answer on Stackoverflow
Solution 10 - JavascriptJHM16View Answer on Stackoverflow
Solution 11 - JavascriptBruno FilgueirasView Answer on Stackoverflow
Solution 12 - JavascriptForwithy NewView Answer on Stackoverflow
Solution 13 - JavascriptMatoeilView Answer on Stackoverflow
Solution 14 - JavascriptNadeem KaziView Answer on Stackoverflow
Solution 15 - JavascriptAdrian GoldaView Answer on Stackoverflow
Solution 16 - JavascriptbriancoderView Answer on Stackoverflow
Solution 17 - JavascriptMohammadreza KhaliliView Answer on Stackoverflow