Skip to content

L.Icon.Default brings a wrong image url #4968

Closed

Description

@ArminMueller
  • [ x] I'm reporting a bug, not asking for help
  • I've looked at the documentation to make sure the behaviour is documented and expected
  • [x ] I'm sure this is a Leaflet code issue, not an issue with my own code nor with the framework I'm using (Cordova, Ionic, Angular, React…)
  • I've searched through the issues to make sure it's not yet reported

The image url leaflet prsents me is https://uismedia.geo-info-manager.com/apis/leaflet_1/imagesmarker-icon-2x.png. It seems there is a missing "/"
Additionally i have an error
leaflet.min.js:5 GET https://uismedia.geo-info-manager.com/apis/leaflet_1/images/ 403 (Forbidden)

Activity

  1. IvanSanchez commented on Sep 28, 2016

    @IvanSanchez
    Member
    • Is there any public webpage in your server we can visit, so we can reproduce the problem ourselves?
    • What OS and web browser are you using?
  2. jasongrout commented on Sep 28, 2016

    @jasongrout

    leaflet.min.js:5 GET https://uismedia.geo-info-manager.com/apis/leaflet_1/images/ 403 (Forbidden)

    This may be from the same issue discussed in #4849

  3. IvanSanchez commented on Sep 28, 2016

    @IvanSanchez
    Member

    Indeed. Which why I'm curious as to know the circumstances this can be reproduced, so we can make unit tests against those.

  4. Greigrm commented on Oct 2, 2016

    @Greigrm

    I had the same issue moving from RC3 to 1.0.1 - in my code I had the line L.Icon.Default.imagePath = 'images'; - can't remember quite why this was, but commenting it out solved the issue - might be worth checking you don't have similar

  5. codeofsumit commented on Oct 15, 2016

    @codeofsumit
    Contributor

    suddenly got the same issue in two completely different projects, both using webpack and leaflet.
    If I add markers to the map, the images aren't found. Browser throws this error:
    image

  6. codeofsumit commented on Oct 16, 2016

    @codeofsumit
    Contributor

    ok I got something.

    So a marker looks like this currently because the images (icon and shadow) aren't found.
    image

    this function in leaflet:

    _getIconUrl: function (name) {
        if (!L.Icon.Default.imagePath) {    // Deprecated, backwards-compatibility only
            L.Icon.Default.imagePath = this._detectIconPath();
        }
    
        // @option imagePath: String
        // `L.Icon.Default` will try to auto-detect the absolute location of the
        // blue icon images. If you are placing these images in a non-standard
        // way, set this option to point to the right absolute path.
        return (this.options.imagePath || L.Icon.Default.imagePath) + L.Icon.prototype._getIconUrl.call(this, name);
    },
    

    causes the data:image urls to have the following string at the end of the url:
    ")marker-icon-2x.png.

    The name of the file can be removed if you delete + L.Icon.prototype._getIconUrl.call(this, name). The ") part is probably from the _detectIconPath regex magic. I can't fix that so I just tried slicing the last two chars off, which results in this function:

    _getIconUrl: function (name) {
        if (!L.Icon.Default.imagePath) {    // Deprecated, backwards-compatibility only
            L.Icon.Default.imagePath = this._detectIconPath();
        }
    
        // @option imagePath: String
        // `L.Icon.Default` will try to auto-detect the absolute location of the
        // blue icon images. If you are placing these images in a non-standard
        // way, set this option to point to the right absolute path.
      var url = (this.options.imagePath || L.Icon.Default.imagePath);
    
      return url.slice(0, - 2);
    },
    

    and here we go, the icon shows up. One last issue is that the shadow image is a marker icon as well - the src path is already wrong, I have no idea why (yet). So a marker now look like this:

    image

    @IvanSanchez does this help you a bit narrowing down the issue?

  7. perliedman commented on Oct 17, 2016

    @perliedman
    Member

    @codeofsumit would be nice to step through _detectIconPath and see what's going on there, especially what value does the path variable have before it's passed through the regex.

  8. codeofsumit commented on Oct 23, 2016

    @codeofsumit
    Contributor

    @IvanSanchez @perliedman I think I found the bug.

    This is _detectIconPath

    _detectIconPath: function () {
        var el = L.DomUtil.create('div',  'leaflet-default-icon-path', document.body);
        var path = L.DomUtil.getStyle(el, 'background-image') ||
                   L.DomUtil.getStyle(el, 'backgroundImage');   // IE8
        document.body.removeChild(el);
    
        return path.indexOf('url') === 0 ?
            path.replace(/^url\([\"\']?/, '').replace(/marker-icon\.png[\"\']?\)$/, '') : '';
    }
    

    the path variable is something like this:
    url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQ…n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=").

    Which is correct.

    Now the regex wants to extract the data.image url from this, and it returns this:

    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQ…n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=")
    

    Notice the last ") that isn't removed from the path variable. The regex /^url\([\"\']?/ only targets url(" at the beginning of the path, not the ") at the end.
    Using this regex works:

    return path.indexOf('url') === 0 ?
        path.replace(/^url\([\"\']?/, '').replace(/\"\)$/, '').replace(/marker-icon\.png[\"\']?\)$/, '') : '';
    

    This fixes the image problem, together with

    var url = (this.options.imagePath || L.Icon.Default.imagePath);
    

    inside_getIconUrl. But it doesn't fix the shadow - I still don't know whats going on with the shadow.

  9. raduflp commented on Oct 23, 2016

    @raduflp

    having the same issue,
    the path value in _detectIconPath is something like "url("data:image/png;base64,i...5CYII=")"
    and it looks like _getIconUrl and _detectIconPath weren't designed to handle data URLs

  10. raduflp commented on Oct 23, 2016

    @raduflp

    the shadow issue seems to be cause by the fact that in _getIconUrl the value for L.Icon.Default.imagePath is already set with the marker data URL, so the image for marker is used and stretched
    image

    could it be related to this commit hardcoding the marker image?
    837d190

  11. codeofsumit commented on Oct 23, 2016

    @codeofsumit
    Contributor

    @Radu-Filip I was able to fix it with these modifications to your PR - I'm not sure what other effects this might have though:
    image

    The problem is - as you said - that the default URL is the marker image, for all icons basically.
    So first of all I added the default URL for the shadow to the CSS:

    /* Default icon URLs */
    .leaflet-default-icon-path {
        background-image: url(images/marker-icon.png);
    }
    
    .leaflet-default-shadow-path {
        background-image: url(images/marker-shadow.png);
    }
    

    Then I passed the name from _getIconUrl to _detectIconPath and used it to add the class to the element from which the path is extracted:

    _getIconUrl: function (name) {
    
      L.Icon.Default.imagePath = this._detectIconPath(name);
    
        // @option imagePath: String
        // `L.Icon.Default` will try to auto-detect the absolute location of the
        // blue icon images. If you are placing these images in a non-standard
        // way, set this option to point to the right absolute path.
      var path = this.options.imagePath || L.Icon.Default.imagePath;
      return path.indexOf("data:") === 0 ? path : path + L.Icon.prototype._getIconUrl.call(this, name);
    },
    
    _detectIconPath: function (name) {
        var el = L.DomUtil.create('div',  'leaflet-default-' + name + '-path', document.body);
        var path = L.DomUtil.getStyle(el, 'background-image') ||
                   L.DomUtil.getStyle(el, 'backgroundImage');   // IE8
    
        document.body.removeChild(el);
    
        return path.indexOf('url') === 0 ? path.replace(/^url\([\"\']?/, '').replace(/(marker-icon\.png)?[\"\']?\)$/, '') : '';
    }
    

    I also had to remove the if/else around detectIconPath, because it wasn't called for the shadow icon. Now everything works for the default marker icon - not sure about custom ones.

  12. raduflp commented on Oct 23, 2016

    @raduflp

    @codeofsumit yeah, i did something similar here https://github.com/Radu-Filip/Leaflet/tree/temp
    and I'll use if for now as a hack. Hopefully there will be a more future proof solution down the line for those using webpack et al

  13. codeofsumit commented on Oct 23, 2016

    @codeofsumit
    Contributor

    @Radu-Filip do you mind updating your PR with that solution? It may get merged.

  14. 81 remaining items

  15. mbrucher commented on Mar 29, 2019

    @mbrucher

    I also have the same issue (webpack using Flask, so all the elements are supposed to be in a static folder), but @Giorgi-M fix is not enough, as I get a '"exports" is read-only' error (Firefox, seems to be linked to the png imports?).
    I see that the issue is closed, but we still see issues with 1.4.0, so I wonder what the fix is?

  16. drakej commented on Apr 4, 2019

    @drakej

    Seeing this issue with vue2-leaflet 2.0.2 and leaflet 1.4.0.

  17. disarticulate commented on Apr 14, 2019

    @disarticulate

    this appears to have existed for quite awhile, and half of the presented solutions don't seem to work.

    Has anyone figured out the root of this problem?

  18. skjortan23 commented on Apr 14, 2019

    @skjortan23

    i am having the same problem with versions "vue2-leaflet": "2.0.3" leaflet "leaflet": "1.4.0".

    also running webpack.

  19. manelclos commented on Apr 14, 2019

    @manelclos

    We are successfully using vue2-leaflet 2.0.3 and leaflet 1.4.0 using a solution found in this same issue:

    import L from 'leaflet'
    require('../../node_modules/leaflet/dist/leaflet.css')
    
    // FIX leaflet's default icon path problems with webpack
    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')
    })
    
  20. drakej commented on Apr 15, 2019

    @drakej

    I guess the better question that needs to be asked is why this wasn't fixed with the merged code which caused the issue to be closed? Since a workaround that works is great, but this should work out of the box and still needs to be an open issue.

  21. ghybs commented on Apr 15, 2019

    @ghybs
    Collaborator

    Dear all,

    Leaflet works out-of-the-box.

    Webpack (and other build engines) combined with Leaflet does not work out-of-the-box.

    Please refer to solution proposed in #4968 (comment): leaflet-defaulticon-compatibility

    While I can understand that many developers would have preferred such feature to be incorporated directly in Leaflet core, it has been argued that the added code is useless to a majority of end-users. Therefore, aligning with Leaflet spirit of keeping its core simple, I decided to make it a plugin.

    With webpack, another typical solution, once you have configured your loaders:

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

    There are other solutions proposed higher in this thread for other build engines and framework combinations.

    To prevent these solutions from being further buried under comments, I am going to lock this thread.

    Thank you all for the shared solutions! 👍

  22. locked as resolved and limited conversation to collaborators on Apr 15, 2019
  23. pinned this issue on Nov 5, 2019
  24. unpinned this issue on May 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    compatibilityCross-browser/device/environment compatibility

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions