Skip to content

fix: prevent duplicate iframes on CldUploadWidget unmount/remount - #658

Merged
PaulBoye-py merged 1 commit into
mainfrom
fix/widget-unmount-duplicate-iframes
Sep 15, 2026
Merged

PaulBoye-py merged 1 commit into
mainfrom
fix/widget-unmount-duplicate-iframes

Conversation

@PaulBoye-py

Copy link
Copy Markdown
Collaborator

Description

When CldUploadWidget unmounts and remounts, next/script's onLoad callback fires again (the script is already cached in the browser, but the callback re-registers on remount). The existing triggerOnIdle callback had no guard against the component unmounting before the idle callback fired, thus allowing a zombie widget instance to be created with an orphaned iframe in the DOM.

Root cause: triggerOnIdle defers widget creation asynchronously via requestIdleCallback. If the component unmounts during that window, the cleanup runs (widget.current = undefined), but the pending idle callback still fires, passes the !widget.current check, and creates a new widget on an unmounted component.

Fix: Add an isMounted ref that gates both the handleOnLoad entry point and the async idle callback. The single cleanup useEffect sets isMounted.current = false before calling widget.current?.destroy(), ensuring no in-flight callbacks can recreate the widget after cleanup.

A manual test page has been added at tests/nextjs-app/app/test-widget/page.tsx to verify the fix via unmount/remount cycling in the browser.

Issue Ticket Number

Fixes #587. Supersedes #588.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have followed the contributing guidelines of this project as mentioned in CONTRIBUTING.md
  • I have created an issue ticket for this PR
  • I have checked to ensure there aren't other open Pull Requests for the same update/change
  • I have performed a self-review of my own code
  • I have run tests locally to ensure they all pass
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes needed to the documentation

When CldUploadWidget unmounts and remounts, next/script's onLoad fires
again. The triggerOnIdle callback had no guard against the component
unmounting before the idle callback fired, allowing a zombie widget to
be created with an orphaned iframe.

Add an isMounted ref that gates both handleOnLoad and the idle callback.
Set isMounted=true on mount; false + destroy on cleanup, in that order.

Closes #587. Supersedes #588.
@vercel

vercel Bot commented Sep 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
next-cloudinary Ready Ready Preview Sep 15, 2026 9:09pm UTC

Request Review

@PaulBoye-py
PaulBoye-py merged commit f3b1fee into main Sep 15, 2026
7 checks passed
@PaulBoye-py

Copy link
Copy Markdown
Collaborator Author

supersedes #588

@PaulBoye-py
PaulBoye-py deleted the fix/widget-unmount-duplicate-iframes branch September 15, 2026 21:12
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.

[Bug] Duplicate iframes created when <CldUploadWidget /> re-renders

1 participant