Search code examples
reactjsleafletreact-leaflet

Map markers in react-leaflet not showing image correctly


I'm confused about creating map markers in react-leaflet; some of the documentation seems to be out of date and I've seen conflicting answers on other sites.

The default <Marker> component from the official documentation's setup, with no icon property described, displays as what looks like a rectangular indent in the map. Essentially it has a shadow but no actual marker icon. If icon is set to a const importing a certain image file, the marker displays as a squashed version of that image. I experimented with setting icon to 'leaflet/dist/images/marker-icon.png' but it looks really odd as the edges are fuzzy and the icon itself looks distorted (compressed horizontally - obviously 25x55 are the dimensions I copied from elsewhere but they don't look right as default).

What's the correct way to render a normal, default, standard map marker in react-leaflet?

My code (with the squashed icon from leaflet/dist) is here:

import './App.css';
import 'leaflet/dist/leaflet.css';
import L, { divIcon } from 'leaflet';
import bear1 from './bulgaria-bear-1.jpg';
import bear2 from './bulgaria-bear-2.jpg';
import bear3 from './bulgaria-bear-3.jpg';
import markerIcon from 'leaflet/dist/images/marker-icon.png';
import React, { useState, useEffect } from 'react';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';

[...]

function PageMap(props) {
  const markerIconConst = L.icon({
    iconUrl: markerIcon,
    iconRetinaUrl: markerIcon,
    iconAnchor: [5, 55],
    popupAnchor: [10, -44],
    iconSize: [25, 55],
  });
  return (
    <div classname="App">
      <MapContainer id="mapid" 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 icon={markerIconConst} position={[51.505, -0.09]}>
          <Popup>
            A pretty CSS3 popup. <br /> Easily customizable.
          </Popup>
        </Marker>
      </MapContainer>
      <p classname="App-header">
        <button onClick={(() => props.navigate('Home'))}>
          Home
        </button>
      </p>
    </div>
  );

As an additional question, I'm wondering why my other CSS doesn't get loaded on the map page, for example the button set as "App-header" which is meant to align with the centre. The button displays but is aligned at left. Does the MapContainer take over the whole page for its own CSS?


Solution

  • Your code looks correct. The dimensions for the Leaflet marker are 24x41. For the button style, add an uppercase "N" to className (instead of classname = "App-header").

    You can find a demo here : Stackblitz