Yves: Best way to wait for CDN scripts to be load?

eliasws
eliasws Tech Lead Posts: 7 🧑🏻‍🚀 - Cadet

We use some third party integrations in our application which are provided by a CDN (e.g. Sentry).

The docs here https://docs.spryker.com/docs/scos/dev/front-end-development/202311.0/yves/adding-and-using-external-libraries-in-yves.html#adding-and-using-external-library-in-your-project-without-npm describe how to include such libraries.

But the second part does not work for us when we try to access the library:

  • in general: How should import nameOfLibrary from './name-of-library' be configured to work if the script is load via script loader?
  • As a workaround we currently use the script by accessing it from `window.*` which leads to a problem that the script is not yet load on init/connectedCallback which leads to a lot of boilerplate:
 protected init(): void {
        this.loadSentry();
    }

    protected loadSentry(): void {
        if (!('Sentry' in window)) {
            // note: seems like the sentry script is not loaded yet so we need to wait for it
            const script = document.querySelector(this.SENTRY_SCRIPT_SELECTOR);
            if (script) {
                script.addEventListener('load', () => {
                    this.initializeSentry();
                });
            }
        } else {
            // sentry is already available
            this.initializeSentry();
        }
    }


Any ideas or suggestions?

Tagged:

Answers

  • Hidran Arias
    Hidran Arias Senior Technical Trainer Sprykee Posts: 60 🏛 - Council (mod)

    How have you added the CDN script?

    You could override the Yves default layout to include your cdn script tag and the Sentry´s init function. In that way, it will be present in all pages.

  • eliasws
    eliasws Tech Lead Posts: 7 🧑🏻‍🚀 - Cadet

    Yes, that how I do it (page-layout-main.twig) so it will be included everywhere. This way it works fine.

    Problem is that the script tag (which loads the library and attaches it to the window) seems to load longer than the moment 'init' or 'connectedCallback' is called?

  • Hidran Arias
    Hidran Arias Senior Technical Trainer Sprykee Posts: 60 🏛 - Council (mod)

    This is what I tested and it works:

    {% block headScripts %}
    <script src='https://js.sentry-cdn.com/gdfg5435435435435b6bceea4985c.min.js' crossorigin="anonymous"></script>"
    
        <script>
    Sentry.onLoad(function () {
    
    Sentry.init({
    dsn: 'https://[email protected]/4506705991696384',
    integrations: [
    Sentry.replayIntegration(),
                    ],
    environment: 'development',
    // Performance Monitoring
    tracesSampleRate:
    1.0, // Capture 100% of the transactions
                    // Session Replay
    replaysSessionSampleRate:
    0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
    replaysOnErrorSampleRate:
    1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
    })
                ;
            });
    //simulate error
          //  callmyApp()
    </script>
    {{ parent() }}
    
    
    {% endblock %}
    

  • eliasws
    eliasws Tech Lead Posts: 7 🧑🏻‍🚀 - Cadet

    Ok, so basically integrating it directly. Basically in a similar fashion to having it in a molecule (waiting 'onload').

  • Hidran Arias
    Hidran Arias Senior Technical Trainer Sprykee Posts: 60 🏛 - Council (mod)

    Yes. Sentry does that already for you. The script loads a very small javascript files that then takes care of loading the rest of Sentry's code