最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Leaflet - Marker image fails to load - Stack Overflow

programmeradmin5浏览0评论

Issue

I'm using leaflet v1.7.1 and react-leaflet v3.0.5 in my React project.

When I try out the setup example in React Router's "Setup" documentation page, the marker icon becomes a broken image as circled in red below:

From the React Router's documentation, this is what the marker should look like:

Upon inspection, the src attribute of the <img> tag that holds the marker image should be /[email protected]/dist/images/marker-icon-2x.png. However, upon inspection, my <img>'s src attribute turns out to be gibberish-looking:

Replication

I've created a new sandbox which contains my code:

Alternatively, follow these steps to replicate the issue:

  1. npx create-react-app leaflet-test

  2. cd leaflet-test/

  3. npm i leaflet react-leaflet

  4. Open the project in code editor. Go to App.js and use the following code:

    import React from "react";
    import "./App.css";
    import "leaflet/dist/leaflet.css";
    import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
    
    const styles = {
      mapRoot: {
        height: 400,
      },
    };
    
    export default function App() {
      return (
        <MapContainer
          style={styles.mapRoot}
          center={[51.505, -0.09]}
          zoom={13}
          scrollWheelZoom={false}
        >
          <TileLayer
            attribution='&copy; <a href=";>OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap/{z}/{x}/{y}.png"
          />
          <Marker position={[51.505, -0.09]}>
            <Popup>
              A pretty CSS3 popup. <br /> Easily customizable.
            </Popup>
          </Marker>
        </MapContainer>
      );
    }
    
  5. npm start

I'm not sure whether I've set-up Leaflet wrongly in React or it's a bug from Leaflet or React Leaflet. Thanks in advance!

Issue

I'm using leaflet v1.7.1 and react-leaflet v3.0.5 in my React project.

When I try out the setup example in React Router's "Setup" documentation page, the marker icon becomes a broken image as circled in red below:

From the React Router's documentation, this is what the marker should look like:

Upon inspection, the src attribute of the <img> tag that holds the marker image should be https://unpkg.com/[email protected]/dist/images/marker-icon-2x.png. However, upon inspection, my <img>'s src attribute turns out to be gibberish-looking:

Replication

I've created a new sandbox which contains my code:

Alternatively, follow these steps to replicate the issue:

  1. npx create-react-app leaflet-test

  2. cd leaflet-test/

  3. npm i leaflet react-leaflet

  4. Open the project in code editor. Go to App.js and use the following code:

    import React from "react";
    import "./App.css";
    import "leaflet/dist/leaflet.css";
    import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
    
    const styles = {
      mapRoot: {
        height: 400,
      },
    };
    
    export default function App() {
      return (
        <MapContainer
          style={styles.mapRoot}
          center={[51.505, -0.09]}
          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={[51.505, -0.09]}>
            <Popup>
              A pretty CSS3 popup. <br /> Easily customizable.
            </Popup>
          </Marker>
        </MapContainer>
      );
    }
    
  5. npm start

I'm not sure whether I've set-up Leaflet wrongly in React or it's a bug from Leaflet or React Leaflet. Thanks in advance!

Share Improve this question edited Feb 23, 2021 at 8:30 AnsonH asked Jan 17, 2021 at 8:05 AnsonHAnsonH 3,2662 gold badges22 silver badges43 bronze badges 3
  • 1 Maybe this thread will help you, good news is that its not your fault and it appears to be a common issue github.com/PaulLeCam/react-leaflet/issues/453 – FoundingBox Commented Jan 17, 2021 at 8:58
  • Thank you so much :D I've found a fix from that issue thread. – AnsonH Commented Jan 17, 2021 at 9:02
  • No problem, happy you found the solution :) – FoundingBox Commented Jan 17, 2021 at 9:03
Add a comment  | 

3 Answers 3

Reset to default 9

I faced Same Issues but found out this solution lately, all we need to do is pass an icon prop to the Marker component.

import marker from '../../Assets/icons/Location.svg';
import { Icon } from 'leaflet'
const myIcon = new Icon({
 iconUrl: marker,
 iconSize: [32,32]
})

<MapContainer center={value} 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={value} icon={myIcon}>
        <Popup>
        Location :{data}
        </Popup>
      </Marker>
    </MapContainer>

Check My Solution on CodeSandBox!

Thanks to FoundingBox's comment, it turns out that this is a bug of React Leaflet.

There is already a GitHub issue thread regarding this bug and this comment suggested the following solution:

OK. It turns out that the problem was caused by including the leaflet CSS in the component's imports.

I've now just included a link to the CDN hosted leaflet.css file and it's working OK, but it would be good if this could be patched to work with create-react-app webpack config.

In other words, here's the step by step guide:

  1. Remove import "leaflet/dist/leaflet.css"; from App.js. Do NOT import the Leaflet CSS from the node modules in any JS files.

  2. Go to public/index.html and include the CDN hosted leaflet.css by pasting the following code in the <head> section of the HTML file:

    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
      integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
      crossorigin=""/>
    

    (Note: This link uses v1.7.1 of Leaflet. Visit Leaflet's documentation to find the code of linking the latest version of Leaflet)

For reference, this is due to webpack rewriting URL's in CSS, whereas Leaflet uses it to detect the paths to its icon images.

See the details in Leaflet issue #4968.

When using Leaflet through a CDN, the Leaflet CSS is not fiddled with, so it works correctly.

You can still use it through webpack, but you should either use only custom icons, or explicitly tell Leaflet where to find the images for its default icon:

import L from 'leaflet';
delete L.Icon.Default.prototype._getIconUrl;

L.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'),
});

I also made specifically a plugin for this case: 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.

import 'leaflet/dist/leaflet.css';
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css'; // Re-uses images from ~leaflet package
import * as L from 'leaflet';
import 'leaflet-defaulticon-compatibility';
发布评论

评论列表(0)

  1. 暂无评论