vue-leaflet/Vue2Leaflet

Defaul Marker Icon loaded though not used

Closed this issue ยท 15 comments

Steps to Reproduce

I'm only using L.DivIcon in my project and not any IconUrl at all.

<l-marker v-for="location in locations" :key="location.id" :lat-lng="location.coordinates">   
  <l-icon class-name="marker-div">
    <div class="marker-icon>
        ***marker html code***
    </div>
 </l-icon>
</l-marker>

Expected Results

marker-icon.png and marker-shadow.png not getting loaded in browser and "marker icon fix" not necessary.

Actual Results

marker-icon.png and marker-shadow.png are still getting loaded and need to be fixed by

import { Icon } from 'leaflet';
delete Icon.Default.prototype._getIconUrl;
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'),
});

which increased the size of the bundle and all browsers download unnecessarily the icons.

Browsers Affected

  • [ x ] Chrome
  • [ x ] Firefox
  • [ x ] Edge
  • [ x ] Safari 9
  • [ x ] Safari 8
  • [ x ] IE 11

Versions

  • Leaflet: v1.6.0
  • Vue: v2.6.11
  • Vue2Leaflet: v2.5.2

@vchrisb This is how leaflet itself handles the icons, you can simply omit:

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

or set it to empty strings to avoid the issue

Thx @DonNicoJs
I tried that already, but marker-icon.png and marker-shadow.png are still tried to be downloaded, this way only from root http://domain.com/marker-icon.png
And there is still unnecessary code added to the bundle.
When setting iconUrl: "" I do get:

Error: iconUrl not set in Icon options (see the docs).
    at NewClass._createIcon (leaflet-src.js?e11e:7132)
    at NewClass.createIcon (leaflet-src.js?e11e:7118)
    at NewClass._initIcon (leaflet-src.js?e11e:7593)
    at NewClass.onAdd (leaflet-src.js?e11e:7500)
    at NewClass._layerAdd (leaflet-src.js?e11e:6617)
    at NewClass.whenReady (leaflet-src.js?e11e:4477)
    at NewClass.addLayer (leaflet-src.js?e11e:6679)
    at VueComponent.addLayer (LMap.js?2699:357)
    at VueComponent.mounted (LMarker.js?4e2b:270)
    at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)

When I using L.divIcon with Leaflet without vue/vue-leaflet, the default marker isn't loaded and I don't need the fix. I think it has to to with how vue-leaflet is handling L.Icon and L.divIcon with l-icon.

@vchrisb just to narrow down the issue how are you loading vue2-leaflet? are you taking advantage of the esm modules and three-shaking?

I have a map component where I do:

import { LMap, LTileLayer, LMarker, LControlZoom, LIcon } from 'vue2-leaflet';
import { latLng, latLngBounds } from 'leaflet';

I haven't done any specific configurations for tree shaking or usage of esm modules. But to be frank, I'm new to vue, webpack and js in general.

@vchrisb Thanks this actually helps! I will try to create a repro case and investigate

Thank you @DonNicoJs!

Might be related: I've been trying to use the "simple example" this morning and the marker is broken on my end as well. I've noticed that for some reason the data-img parameter is not correctly formed an has ")marker-icon.png injected at the end of the base64 string.

The shadow pane element also sees a ")marker-shadow.png added to the end of the base64 string but if I remove it I get the marker as a shadow, and not a properly formed shadow.

@fbnlsr this is a different issue directly related to leaflet with webpack.
At top of the FAQ are a few solutions linked. https://vue2-leaflet.netlify.app/faq/

import { Icon } from 'leaflet';
delete Icon.Default.prototype._getIconUrl;
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'),
});

can be used to fix it, but this issue here is regarding using no default marker at all.

Woops you're right, sorry about that. You can disregard my comment. Thanks! ๐Ÿ˜…

@DonNicoJs I've created a codesandbox for the issue: https://codesandbox.io/s/vigilant-jang-2gs16

Steps to reproduce:

  • Open the sandbox in Chrome
  • Open Network Tab in Developer tools
  • Clear
  • click "Show Icon"

You should see marker-icon.png and marker-shadow.png being loaded, though not used to render.

Here is also a very simple Leaflet only example: https://jsfiddle.net/7qnht32o/1/
If you observe network tab, no icons loaded.

Thx!

@vchrisb Thank you! This is helpful!

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@DonNicoJs anything else I can help with?

I do not know how it effects a bundle size, but the following lines let me get rid of "net::ERR_INVALID_URL" errors in Chromium (I experienced the same or similar issue as @fbnlsr described) without the need to import the icon or the shadow.

import { Icon } from 'leaflet'

// The following helps to avoid "net::ERR_INVALID_URL" errors in Chromium-like browsers without the need to unnecessarily import the files.
Icon.Default.prototype.options.imagePath = '.'
Icon.Default.prototype.options.iconUrl = ''
Icon.Default.prototype.options.shadowUrl = ''

I consider it as a workaround though. I believe I also checked some other configurations like setting imagePath to an empty string and iconUrl to null or undefined, but none of them worked. I think it also may stop working in some later Leaflet releases (I think I've seen the imagePath commented as "legacy" or something in their code).

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.