Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(scripts): prevent scope disposal from aborting unrelated trigger in useScript#660

Merged
harlan-zw merged 1 commit intounjs:mainfrom
cernymatej:fix/script-trigger-race
Feb 24, 2026
Merged

fix(scripts): prevent scope disposal from aborting unrelated trigger in useScript#660
harlan-zw merged 1 commit intounjs:mainfrom
cernymatej:fix/script-trigger-race

Conversation

@cernymatej
Copy link
Contributor

@cernymatej cernymatej commented Feb 17, 2026

πŸ”— Linked issue

fix nuxt/scripts#597

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

This fixes a problem where a stale Vue scope disposal could abort an unrelated trigger during client-side navigation.

When navigating between pages that both use useScript with the same src, the new page mounts before the old page unmounts. The old page's onScopeDispose called abort() on script._triggerAbortController, which by that point was the new scope's controller. This cancelled the new page's trigger and prevented the script from ever loading.

const idx = script._triggerPromises.push(Promise.race([
trigger.then(v => typeof v === 'undefined' || v ? script.load : undefined),
script._triggerAbortPromise,
abortPromise,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really sure why this was attached to the script object since - if I didn't miss anything - it was only used in this place πŸ€”

can't we just pass in a variable?

@ianjamieson
Copy link

If anyone comes across this, I had been using the code below which was encountering this bug.

useScript(
  {
    src: 'https://script.com/script.js',
    crossorigin: false,
  },
  {
    trigger: useScriptTriggerElement({
      trigger: 'visible',
      el: container,
    }),
  },
);

I have temporarily fixed it with:

useScript(
  {
    src: 'https://script.com/script.js',
    crossorigin: false,
  },
  {
    trigger: (load) => {
      const { stop } = useIntersectionObserver(
        container,
        (entries) => {
          if (entries[0]?.isIntersecting) {
            load();
            stop();
          }
        },
      );
    },
  },
);

@harlan-zw harlan-zw merged commit e8f5b4b into unjs:main Feb 24, 2026
1 of 2 checks passed
@harlan-zw
Copy link
Collaborator

Thanks for working on this, looks good :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

YouTube players break on client-side navigation

3 participants