next/script onReady does not fire when rendering multiple instances with the same src
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
Link to the code that reproduces this issue
https://github.com/carlyle/next-script-onready-reproduction-app
To Reproduce
You can see it on a built and deployed app:
- Go to https://next-script-onready-reproduction-app.vercel.app/single. Verify that
Embed #1renders without error and with ✅s by "Loaded?" and "Ready?", which is expected - Go to https://next-script-onready-reproduction-app.vercel.app/multiple. Embed 1 renders without error and with ✅s by "Loaded?" and "Ready?" but the following embeds do not render as expected
As well as in local development:
- Start the application (
next dev) - Go to http://localhost:3000/single. Verify that Embed 1 renders without error and with ✅s by "Loaded?" and "Ready?", which is expected
- Go to http://localhost:3000/multiple. Embed 1 renders without error and with ✅s by "Loaded?" and "Ready?" but the following embeds do not render as expected
Current vs. Expected behavior
Current Behavior
The first instance of <Script> with a particular src:
- fires the
onLoadcallback as expected - fires the
onReadycallback as expected
The second instance of <Script> with the same src:
- sometimes fires the
onLoadcallback, which is unexpected because it is intended for "run[ning] JavaScript code once after the script has finished loading" - does not fire the
onReadycallback, which is unexpected because it is intended for "run[ning] JavaScript code after the script has finished loading and every time the component is mounted"
The third and later instances of <Script> with the same src:
- do not fire the
onLoadcallback, which is expected - do not fire the
onReadycallback, which is unexpected because it is intended for "run[ning] JavaScript code after the script has finished loading and every time the component is mounted"
Expected Behavior
The first instance of <Script> with a particular src:
- fires the
onLoadcallback - fires the
onReadycallback
The second and later instances of <Script> with the same src:
- do not fire the
onLoadcallback - fire the
onReadycallback
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 23.3.0: Wed Dec 20 21:31:00 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6020
Available memory (MB): 32768
Available CPU cores: 12
Binaries:
Node: 20.11.0
npm: 10.2.4
Yarn: N/A
pnpm: N/A
Relevant Packages:
next: 14.2.0-canary.22 // Latest available version is detected (14.2.0-canary.22).
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0
typescript: 5.1.3
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
App Router, Script optimization (next/script)
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local), Vercel (Deployed), Other (Deployed)
Additional context
The motivation behind having a <Script> render within each instance of <Embed>, as opposed to having a single <Script> somewhere else in the app, is:
- to keep all of the embed-related logic in one place
- to prevent the remote script from loading if we don't end up rendering an embed
An example use case would be embedding videos in news articles: we want to load the video player library whenever an article has any video embeds, but wouldn't want to load that library unnecessarily on articles without video embeds
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked reproduction app and compare the /single and /multiple routes in next dev or a deployed build. Then inspect the next/script implementation and its callback handling for repeated instances with the same src; done means later instances consistently fire onReady while only the first fires onLoad.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nextjs, react
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100