Injected javascript loaded after turbo:load

Hi,

I’m adding a new javascript library to the head of a particular page as I don’t want it on all pages (as it’s rather large). The handbook says that this is supported.

However, while the script tag is injected in to the head correctly, the replacement of the body (by turbo drive) is executed immediately and, therefore, the script has not been loaded at this point (as it would be if you simply loaded the page without turbo).

Furthermore, the turbo:load event is fired before the script has finished loading as well, so I can’t use that either.

I can, of course, wait for the load event of the particular script to fire but this seems like something turbo should handle for me? I think mirroring the way the standard page model works as closely as possible would make this easier for everyone? Could you, for example, automatically add load event listeners to injected scripts and wait for them (when not defer or async) to load before updating the html and then triggering the turbo:load event? This would also help with Stimulus controllers which are mutationobserver based (and get initialised before the turbo:load) event as well?

Hello again, this seems to still be an issue for me. Does anyone know how to solve it in a good way?!

Are you using stimulus with turbo?
Are you using webpacker or something similar?

Yup. stimulus and webpack… I opened an issue over here as well: Pause render until new head scripts are loaded · Issue #377 · hotwired/turbo · GitHub

Would Dynamic module import with Stimulus JS work for your scenario?

That does not work, sadly.

In this particular instance, I’m referencing the Stripe js sdk using a tag in the head (as their documentation suggests that it must be this way for regulatory purposes).

So, it’s not possible to import the stripe library in to the stimulus controller as you would normally. Instead, I add the stripe tag only to the billing pages and then use a stimulus controller to use the stripe sdk.

The problem then is that with a turbo visit to that page (as opposed to a normal page load) the stimulus controller can be instantiated before the stripe script has loaded.

In my referenced GitHub issue I mention that this breaks the normal contract of a page render in that I’d expect (non-defer, non-async) scripts to be added to the head AND loaded before the body is rendered.

One workaround is to use the following on these pages (but that’s a bit rubbish) and the other workaround is to wait for the load event on the manually but, as I said, I think turbo should do that for you.

<meta name="turbo-visit-control" content="reload">

@markjerz - I’d be willing to look at a demo app, but I do not currently have/use stripe to help troubleshoot the issue.