next.js: next/script does not trigger onLoad callback when used with beforeInteractive strategy

Run next info (available from version 12.0.8 and up)

No response

What version of Next.js are you using?

11.1.2

What version of Node.js are you using?

14.15

What browser are you using?

Chrome

What operating system are you using?

Linux

How are you deploying your application?

next dev

Describe the Bug

According to the docs, onLoad callback of next/script component can be used either with beforeInteractive and afterInteractive strategies. But when using with beforeInteractive strategy, onLoad callback never gets called.

Expected Behavior

Expect onLoad callback to be called when loading script with beforeInteractive strategy

To Reproduce

Using the same example of the docs, with stripe script: hasLoaded is never set to true and stripe has loaded never gets printed. I get the same behavior in the latest version of next.

Here is a minimal reproducible repo: https://github.com/loft-br/before-interactive-on-load-bug image

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 8
  • Comments: 16 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Me and my team are struggling with this exact issue right now. I created the issue #33402 on documentation inconsistencies, but would also like to see some sort of a resolve to this.

Our use case is following: we use two next/script elements to load two external scripts: the first one loads a cookie consent SDK and the second loads our analytics library. Both of the script elements have their own onLoads for initialization.

The problem is that the analytics library depends on the cookie consent SDK, so we need to load and initialize that one first. Also, both of these scripts need to be initialized before any React useEffect hooks are run, because that’s where the tracking functions of the analytics library are to be used.

Now, because onLoads for these scripts are just silently ignored, we can’t do initialization on neither of these libraries.

We are having the same issue with beforeInteractive and onLoad as the code inside onLoad had never being executed.

Here is the sample code inside _app.tsx:

Screen Shot 2022-01-19 at 2 57 28 pm

With a simple code inside script1.js to be

console.log('loading script1.js');

And script2.js:

console.log('loading script2.js');

Then we have the output of

loading script1.js
loading script2.js
afterInteractive onLoad()

The documentation does not use strategy="beforeInteractive" when loading a third-party, but your example did.

Removing that prop loads it correctly. So just curious if it was a misunderstanding or just a bad reproduction?

What is your use case by the way? What kind of third-party script do you try embedding with the beforeInteractive strategy?

Sorry if I’m missing something, but this is not about inline scripts at all. It is a third party script just like the example in the docs. Perhaps this part of the docs should be updated then if this is expected

Some third-party scripts require users to run JavaScript code after the script has finished loading in order to instantiate content or call a function. If you are loading a script with either beforeInteractive or afterInteractive as a loading strategy, you can execute code after it has loaded using the onLoad property:

Sorry for all the confusion folks.

@davidbarker you are indeed correct that the documentation is wrong.onLoad does not work when used with the beforeInteractive strategy. Thanks for creating https://github.com/vercel/next.js/pull/36261 to add a note for this, we also have https://github.com/vercel/next.js/pull/36453 in the pipeline to fix that incorrect sentence.