Marcus Junius Brutus
Marcus Junius Brutus

Reputation: 27296

marker icon isn't showing in Leaflet

I 've put together a very simple React / Leaflet demo but the marker icon is not showing at all. Full running code is here.

Here's what I have in my componentDidMount method:

componentDidMount() {
this.map = L.map("map-id", {
  center: [37.98, 23.72],
  zoom: 12,
  zoomControl: true
});

const mapboxAccessToken =
  "pk.eyJ1IjoibXBlcmRpa2VhcyIsImEiOiJjazZpMjZjMW4wOXJzM2ttc2hrcTJrNG9nIn0.naHhlYnc4czWUjX0-icY7Q";
L.tileLayer(
  "https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}",
  {
    attribution:
      'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
    maxZoom: 25,
    id: "mapbox/streets-v11",
    accessToken: mapboxAccessToken
  }
).addTo(this.map);

L.marker([37.98, 23.72])
  .addTo(this.map)
  .bindPopup("a marker")
  .openPopup();
}

Basically, the popup is visible, but not the marker icon itself. I.e., here's what I see:

enter image description here

Upvotes: 14

Views: 34740

Answers (8)

Juan Giacosa
Juan Giacosa

Reputation: 194

For those of You using typescript, this might be of use:


Remember to update both leaflet and @types/leaflet


My default marker was showing locally but displayed as a broken image in staging. I checked my current version with npm outdated and saw that leaflet wasn't outdated, buuuut @types/leaflet was.

Once I updated the types definition package, the marker showed with no problems. So please, remember to update both of your packages.

Upvotes: 0

Matielo Geronimo
Matielo Geronimo

Reputation: 1

 L.Icon.Default.imagePath='/path_to_your_images';
    var icon = L.icon({
        iconUrl: 'marker-icon.png',
        shadowUrl: 'marker-shadow.png',

        iconSize:     [25, 41],
        shadowSize:   [30, 65],
        iconAnchor:   [12, 41],
        shadowAnchor: [7, 65]
    });

this solution works for me!

Upvotes: 0

Eyosi_G
Eyosi_G

Reputation: 61

include this before in index.js file before calling render function.

import markerIcon from "../node_modules/leaflet/dist/images/marker-icon.png";
L.Marker.prototype.setIcon(L.icon({
  iconUrl:markerIcon
}))

Upvotes: 5

ninja
ninja

Reputation: 387

I guess one simple way is just changes the image path:

L.Icon.Default.imagePath='images/'

I'm using react so I copied the folder /node_modules/leaflet/dist/images to /public.

Upvotes: 3

kybernetikos
kybernetikos

Reputation: 8699

I'm using react-leaflet. Here's how I did it.

import markerIconPng from "leaflet/dist/images/marker-icon.png"
import {Icon} from 'leaflet'

then, later, inside the MapContainer:

<Marker position={[lat, lng]} icon={new Icon({iconUrl: markerIconPng, iconSize: [25, 41], iconAnchor: [12, 41]})} />

Upvotes: 33

ghybs
ghybs

Reputation: 53290

Just for reference, this is due to webpack trying to include the Marker Icon image file specified in Leaflet CSS as a static asset in different folder and possibly file renaming (e.g. for finger printing); all this interferes with Leaflet algorithm which uses that image only as a pointer to its actual CSS images folder, which therefore can be completely missing after webpack build step.

See details in https://github.com/Leaflet/Leaflet/issues/4968

I specifically made a Leaflet plugin to cover this issue: https://github.com/ghybs/leaflet-defaulticon-compatibility

Retrieve all Leaflet Default Icon options from CSS, in particular all icon images URL's, to improve compatibility with bundlers and frameworks that modify URL's in CSS.

Unfortunately, it would still not work in CodeSandbox (or even in StackBlitz), because the latter does not handle these static assets. It is visible by just trying to use Leaflet Layers Control, which uses a very simple CSS background image, which is also missing in CodeSandbox.

But everything should be fine in your own environment.

demo in CodeSandbox: https://codesandbox.io/s/elegant-swirles-yzsql

and in StackBlitz (same static assets issue): https://stackblitz.com/edit/react-vqgtxd?file=index.js

Upvotes: 2

Marcus Junius Brutus
Marcus Junius Brutus

Reputation: 27296

Here's what worked for me in the end (I'm on webpack):

const defaultIcon = new L.icon({
  iconUrl: require('../node_modules/leaflet/dist/images/marker-icon.png'); // your path may vary ...
  iconSize: [8, 8],
  iconAnchor: [2, 2],
  popupAnchor: [0, -2]
});

generateMarkers().forEach( c=> {
   L.marker(c, {icon: defaultIcon}).addTo(this.map).bindPopup('a marker; yeah').openPopup();
}

Upvotes: 4

Max
Max

Reputation: 1048

Try to add an icon:

const myIcon = L.icon({
   iconUrl: 'myIcon.png',
   // ...
});

L.marker([37.98, 23.72], {icon: myIcon})
  .addTo(this.map)

Perhaps you have some problems with the default one: https://leafletjs.com/reference-1.6.0.html#icon-default

Upvotes: 7

Related Questions