1

I'm trying to use a custom icon with markers with react-leaflet

Following the indications found here: https://leafletjs.com/examples/custom-icons/ and here: https://roblahoda.com/blog/leaflet-react-custom-icons/

I added these lines of code:

import Leaflet from 'leaflet'
import "leaflet/dist/leaflet.css"

import React from 'react'
import {
  TileLayer,
  LayersControl,
  LayerGroup,
  useMap,
  useMapEvents,
  GeoJSON,
  Marker,
  Popup,
} from 'react-leaflet'

export const newicon = new Leaflet.Icon({
  iconUrl: ("../../..assets/marker.svg"),
  iconAnchor: [5, 55],
  popupAnchor: [10, -44],
  iconSize: [25, 55],
})

And for the Marker I specified the newicon :

    <Marker position={getMarkerPosition(state_name)} icon={newicon}>

(base) raphy@pc:~/Raphy-Template/src/assets$ ls -lah
    total 56K
    -rw-rw-r--  1 raphy raphy 5.0K Jan 31 11:40 marker.png

But the new icon is not properly rendered:

enter image description here

Update 1)

Using require:

export const newicon = new Leaflet.Icon({
  iconUrl: require("../../../assets/marker.svg"),
  iconAnchor: [5, 55],
  popupAnchor: [10, -44],
  iconSize: [25, 55],
})

I get this error: Module not found: Error: Can't resolve '../../../assets/marker.svg'

With import instead if require I do not get any error, but still the icon doesn't show up:

export const newicon = new Leaflet.Icon({
  // @ts-ignore
  iconUrl: import("../../../assets/svg/push_pin_black_36dp.svg"),

  iconAnchor: [5, 55],
  popupAnchor: [10, -44],
  iconSize: [25, 55],
})


(base) raphy@pc:~/Raphy-Template/dist/assets/svg$ ls -lah
    -rw-rw-r-- 1 raphy raphy  390 Jan 31 19:05 
push_pin_black_36dp.svg
    (base) raphy@pc:~/Raphy-Template/dist/assets/svg$ 

Other info:

I've put the code inside this CodeSandbox repo: https://codesandbox.io/s/damp-tdd-i917u?file=/src/App.js

"react": "^17.0.2"
"react-leaflet": "^3.2.5"
node: v16.13.0
O.S.: Ubuntu 20.04 Desktop

How to make the custom icon appear?

Raphael10
  • 2,508
  • 7
  • 22
  • 50

1 Answers1

1

Remember that your React app project is built and moved to another place in your file system. In particular, assets like your icon image / SVG may not be bundled, or placed in a different position relatively to your script.

In the blog about React Leaflet with custom icons you refer to, notice how the path to the image assets is specified: it uses require("some/path"), which webpack understands as a directive to bundle the specified asset and provide the resulting built path.

So in your case, you would simply do:

export const newicon = new Leaflet.Icon({
  iconUrl: require("../../../assets/marker.svg") // require the path to the asset
})

That being said, it looks like some build engine configurations convert the require('path/to/some/svg') as a React component-like object (much probably to be able to use SVG as if it were a React component, see https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs), and provide the built URL in the Url property of such object:

export const newicon = new Leaflet.Icon({
  iconUrl: require("../../../assets/marker.svg").Url // require the path to the asset
})

Another option is to use a more standard import at the beginning of the file. In this case, with the same build engine configuration as provided in your CodeSandbox, it just gives the resulting URL as expected (which is actually an inlined Base64 data):

import iconUrl from "./svg/push_pin_black_36dp.svg";

export const newicon = new Leaflet.Icon({
  iconUrl
});

Demo: https://codesandbox.io/s/quiet-shape-6ise9?file=/src/App.js

ghybs
  • 47,565
  • 6
  • 74
  • 99
  • Hi @ghybs ! Thanks for helping!! With `require` I get this error `Module not found: Error: Can't resolve '../../../assets/marker.svg'` . I update my post above. Should I modify/add something in order to use `require` ? `require` is the only way to make it work? I ask you that, because in the `renderer` process of `Electron` app I'm not able to use it – Raphael10 Jan 31 '22 at 17:20
  • The most probable explanation is that your path is incorrect within the file structure of your React project source code, but without any details on it, I can only make blind guesses. You can also use `import`, but that should not change anything here. – ghybs Jan 31 '22 at 17:30
  • With `import` instead of `require` I do not get any error, but still the icon doesn't show up – Raphael10 Jan 31 '22 at 18:14
  • As said above, without further details on your project file structure, I cannot provide any useful help. Ideally share a live reproduction example, e.g. using CodeSandbox or StackBlitz. – ghybs Jan 31 '22 at 18:30
  • I've put the code inside this `CodeSandbox` repo: https://codesandbox.io/s/damp-tdd-i917u?file=/src/App.js – Raphael10 Feb 09 '22 at 09:49