react-leaflet map not correctly displayed
Asked Answered
S

19

91

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 ?

Sarette answered 1/11, 2016 at 17:33 Comment(0)
C
129

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

Cornea answered 1/11, 2016 at 17:56 Comment(7)
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.Sarette
@Sarette 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.Cornea
The problem remains the same. I try with [email protected] and [email protected] and also with [email protected] and [email protected]. I also fix the height of my component using <div id={style.map}> with #map { height: 300px }Sarette
I got it ! You have to setup the height of .leaflet-container alsoSarette
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, })Sydney
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.Count
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...Zannini
P
70

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>

Paripinnate answered 2/4, 2020 at 14:22 Comment(3)
Thanks, just need to correct the letter at the width style={{ height: '100vh', width: '100wh' }}Cribriform
Thank you, for me was the important thing to add import 'leaflet/dist/leaflet.css';Roland
import 'leaflet/dist/leaflet.css'; in the file where you use Map from react-leaf. worked for meNidus
E
31

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

import 'leaflet/dist/leaflet.css';
Ectomy answered 17/4, 2019 at 18:32 Comment(0)
G
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>
    )
}
}
Glide answered 17/5, 2019 at 13:3 Comment(3)
its helps to see the map. but i steel not see the marker iconSoni
no... this solve my problem --> Leaflet.Icon.Default.imagePath = '//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.4/images/';Soni
this one works as charm, I finally could use itHike
W
17

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;
}
Walloper answered 25/1, 2021 at 23:16 Comment(1)
This is smart it workedOcasio
B
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.

Blackshear answered 24/9, 2018 at 14:11 Comment(0)
K
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

Kelsey answered 16/8, 2019 at 20:0 Comment(0)
X
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

Xeres answered 27/11, 2020 at 0:7 Comment(0)
R
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

Roofing answered 5/2, 2021 at 1:34 Comment(0)
S
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/[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>
Sharitasharity answered 13/4, 2019 at 7:11 Comment(0)
I
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

Incredulous answered 1/1, 2020 at 19:3 Comment(0)
C
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'));
Cubic answered 17/11, 2020 at 14:42 Comment(0)
O
1

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

It seems you also have to add:

.leaflet-container{
  height:500px;
}
Operant answered 9/4, 2021 at 2:30 Comment(0)
A
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.

Allman answered 11/5, 2022 at 7:29 Comment(0)
S
1

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

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
Situated answered 22/2, 2023 at 9:53 Comment(0)
L
1

For Next.js App Router

globals.css

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

MapComponent.tsx

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

export default function MapWithMarkers() {
  return (
    <div className="flex justify-center w-full overflow-hidden">
      <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>
    </div>
  );
}
Linearity answered 20/3 at 17:41 Comment(0)
B
0

try this :

 var mapid = $(this).find('[id^=leaflet-map]').attr('id');
      var map = settings.leaflet[mapid].lMap;
      map.invalidateSize();
Bernardina answered 6/1, 2020 at 15:5 Comment(0)
S
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'>
Shuffleboard answered 28/10, 2020 at 5:8 Comment(0)
D
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/[email protected]/dist/leaflet.js"
      integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
      crossorigin=""></script>
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
Debus answered 23/11, 2020 at 8:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.