Mapbox-gl-js: Relative URLs in sources don't work anymore (0.27.0)

Created on 16 Nov 2016  路  11Comments  路  Source: mapbox/mapbox-gl-js

With version 0.26.0 I had something like this:

"sprite": "/mapbox-gl-styles/sprites/bright-v9",
"glyphs": "/mapbox-gl-styles/glyphs/{fontstack}/{range}.pbf",

in my style definition, because I wanted it to work in all environments. Now with 0.27.0, the function parseUrl throws an error because the URL doesn't match the expected syntax (protocol missing):

https://github.com/mapbox/mapbox-gl-js/blob/44727a70955a77ef5fbf3c46aa52160af0b2e086/js/util/mapbox.js#L93

I guess the protocol could be retrieved, if missing, with location.protocol ; but I'm not good enough with regexs to fix it myself... :) Here, if the regex doesn't match, it returns null.

Thanks.

Most helpful comment

Since my production environment is not connected to the internet, this was keeping me from upgrading mapbox-gl.js...

My fix for this turned out to be the same one I used for the tiles.

from the json file in my project-
"sprite": "https://replacemewiththehostnameplease:4567/myfolder/style/bright/sprite",

then in the js code:
jQuery.get('/myfolder/tweakedstyle.json', function(theTweakedJson) {
var theStringifiedTweakedJson = JSON.stringify(theTweakedJson);
theStringifiedTweakedJson = theStringifiedTweakedJson.replace(/replacemewiththehostnameplease/g, window.location.hostname);
theTweakedJson = JSON.parse(theStringifiedTweakedJon);
...
then I feed it to the map constructor thingy:

    map = new mapboxgl.Map({
        container: 'map',
        style: theTweakedJson,

....

seems to work like a champ.

All 11 comments

It wasn't intended for sprite and glyphs properties to support relative URLs; if it worked in past versions, it was an accident.

because I wanted it to work in all environments

Can you say what specifically you mean by this?

I mean that each environment retrieves its own glyphs and fonts: local from local, staging from staging, prod from prod... So I didn't need to hard code each URLs for each environment.

It is a reasonable expectation that relative URLs would work.

I don't think it's something we should support.

  • There's ambiguity about what the URL should be relative to. Should it be the style URL or the page URL?
  • If it's the style URL, then it needs explicit code and acts differently than relative URLs elsewhere in Web APIs.
  • If it's the page URL, then it's a style spec feature that can never be replicated in gl-native.

Use cases where relative URLs are desired can be satisfied by preprocessing the style to produce the desired absolute URL.

Those are good points. 馃憤 Let's close this ticket and open another to consider adding this rule to the validator.

Since my production environment is not connected to the internet, this was keeping me from upgrading mapbox-gl.js...

My fix for this turned out to be the same one I used for the tiles.

from the json file in my project-
"sprite": "https://replacemewiththehostnameplease:4567/myfolder/style/bright/sprite",

then in the js code:
jQuery.get('/myfolder/tweakedstyle.json', function(theTweakedJson) {
var theStringifiedTweakedJson = JSON.stringify(theTweakedJson);
theStringifiedTweakedJson = theStringifiedTweakedJson.replace(/replacemewiththehostnameplease/g, window.location.hostname);
theTweakedJson = JSON.parse(theStringifiedTweakedJon);
...
then I feed it to the map constructor thingy:

    map = new mapboxgl.Map({
        container: 'map',
        style: theTweakedJson,

....

seems to work like a champ.

Thanks @brianssheldon I can confirm it works. A bit hacky, but, meh :) Could there be any performance issue with this way of loading the styles?

@nicooprat pretty hacky for sure. I don't know about there being a performance issue. I don't see it being much worse than going to mapbox for the files. Also, I think this is only done when the page is loaded so once it's up and running it should be fine. But I'm no expert on js or mapbox.

I had to just push my project to master first, so instead of setting:

"sprite": "/assets/sprites"

I have set:

"sprite": "https://mapillary.github.io/mapillary_solutions/my_map/assets/sprites"

It just seems silly because I can't preview my map before uploading the first time, since I'm pushing the whole thing to master anyway, therefore validating the hosted URL.

For others running into this issue, a workaround like this may be helpful, if you're constructing your style file on the fly:

sprite: `${window.location}path/to/my/sprite`

For a cleaner solution than altering style JSON files, you can also use transformRequest as outlined in the comment in https://github.com/mapbox/mapbox-gl-js/pull/9225#issuecomment-578089885.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jfirebaugh picture jfirebaugh  路  3Comments

iamdenny picture iamdenny  路  3Comments

aaronlidman picture aaronlidman  路  3Comments

BernhardRode picture BernhardRode  路  3Comments

foundryspatial-duncan picture foundryspatial-duncan  路  3Comments