4

I was trying to use Mapbox in an LWC component, by importing its library using loadScript, but I am only getting an undefined error in the promise.

I created a ZIP bundle with the CSS and JS files (mapbox.css and mapbox.js), and also a test JS file to check there is no problem with the ZIP itself (example.js with a console.log message).

I have uploaded it using the Metadata API, and set it as an application/zip, here is the XML file contents:

<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
    <cacheControl>Private</cacheControl>
    <contentType>application/zip</contentType>
</StaticResource>

This is the example code I am trying to run:

import { api, LightningElement } from 'lwc';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import MAPBOX from '@salesforce/resourceUrl/mapbox';

export default class InquiryMap extends LightningElement {
    @api recordId;
    mapboxInitialized = false;

    renderedCallback() {
        this.bootMapbox();
    };

    bootMapbox() {
        if (this.mapboxInitialized) {
            return;
        }

        this.mapboxInitialized = true;
        
        loadStyle(this, MAPBOX + '/mapbox.css')
        .then(() => {
            console.log('Mapbox CSS is ready! =)');
        })
        .catch((err) => {
            console.log('Error (CSS)', err);
        });

        loadScript(this, MAPBOX + '/example.js')
        .then(() => {
            console.log('Mapbox Example JS is ready! =)');
        })
        .catch((err) => {
            console.log('Error (Example)', err);
        });

        loadScript(this, MAPBOX + '/mapbox.js')
        .then(() => {
            console.log('Mapbox JS is ready! =)');
        })
        .catch((err) => {
            console.log('Error (JS)', err);
        });
    };
}

But this is the output in the console:

I am a example JS file
Mapbox Example JS is ready! =)
Mapbox CSS is ready! =)
Error (JS) undefined

The line with the content Mapbox Example JS is ready! =) is from the example.js file.

I have checked the files are OK by opening them in a browser window in the Salesforce URL, and everything looks fine, but as I am not getting any details about the error I do not know what can I do.

mapbox.js load mapbox.js contents

The contents of the failing JS library can be found here: Mapbox GL 2.0.1.

Any help would be much appreciated!

0

1 Answer 1

8

Upon debugging with the Regular Mapbox GL regular version using the Salesforce Locker Console discovered that the issue is because the CSP required for getting this working is not supported by Salesforce Locker service.

worker-src blob child-src blob are not supported MIME types in the locker.

Next, I discovered that Mapbox provides an alternative approach documented in this section for sites that have a Strict CSP policy. This is documented here.

Upon using this approach I discovered that there is this error that pops up

Error (JS) TypeError: a.Worker is not a constructor at new gp (mapbox:1) at xp.acquire (mapbox:1) at new Eh (mapbox:1) at new Id (mapbox:1) at Map._updateStyle (mapbox:1) at Map.setStyle (mapbox:1) at new Map (mapbox:1) at eval (mapbox.js:67)

This error is because the Locker Service prevents the use of JavaScript Worker

Here are a few suggestions I would like to leave here

  1. Use the out of box base component using the lightning-map component

If the above does not meet then use the below options

  1. Use a Visualforce and iframe the page inside the LWC Component. Using this approach there won't be any locker restrictions.
  2. Reach out to MapBox support to see if they have any recommendations. Is there an alternative SDK without using the Javascript worker? You can point them to this post.
7
  • If you have to use Visualforce and iframe be careful about URLs - there is no API in Salesforce to generate a VF URL from a Lightning context or vice versa. If you are able to rely on redirection of URL then "/apex/PageName" will work. Next worry about how to communicate between the Visualforce page and the LWC. If you are in a community you cannot use Lightning Message Service, and there is no real viable approach since the standard pubsub code does not work in this scenario.
    – Phil W
    Commented Dec 27, 2020 at 8:44
  • @phil W The LMS is available from spring 21 for communities as well! Note you can always use post messages to post messages. The Salesforce Map component uses iframe and uses window.postMesages to communicate Commented Dec 27, 2020 at 13:34
  • good to know that community support is on the way. As to post message, this only works when the locker service permits it (so certainly not across package namespace boundaries, for example).
    – Phil W
    Commented Dec 27, 2020 at 13:54
  • 1
    Any update on this locker issue topic for mapbox ? Trying to integrate it in a lwc but probably facing the same issue now..
    – Péqueño
    Commented Apr 12, 2022 at 9:39
  • 2
    Answering myself, found the following documentation from mapbox regarding strict CSP : docs.mapbox.com/mapbox-gl-js/guides/browsers-and-testing/…
    – Péqueño
    Commented Apr 12, 2022 at 9:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .