window.open. Browsers only allow that call while the user’s click is still considered active. Anything that delays the popup until after that gesture expires can make the browser treat it as unsolicited.
When this happens, you can expect an OAuthBlockedError in the onError callback of paragon.connect. Then look for work that runs between the click and window.open, so installFlow.start (or connect / installIntegration) still happens in the click handler.
Symptoms
- Clicking Connect does nothing, or a spinner never ends.
- Chrome or Safari shows a blocked-popup indicator.
- Connect SDK
onErrorreceives:
Cause
The OAuth prompt uses a popup. Chrome and Safari allowwindow.open when it runs in the same turn as a user gesture. They block it when the gesture has expired.
The delay can come from several places. One of them is calling paragon.authenticate inside the click handler. Others include lazy-loading the SDK on click, awaiting a JWT, analytics, or a slow network after the click. A handler that stacks several of those steps looks like this:
Fix
1. Confirm it is a popup block
In a Headless Connect Portal, inspecterror.name in onError. If it is OAuthBlockedError, this article applies.
If you are using the hosted Connect Portal, check the browser’s popup indicator on your app origin.
2. Keep the Connect click free of awaits
Start the install in the click handler with no async work in front of it. If you currently authenticate on click, moveparagon.authenticate to page load or app start instead. Displaying the Connect Portal already recommends that for token freshness. It also happens to keep authenticate off the click path.
@useparagon/connect before the click, and do not await analytics or a JWT fetch before start / connect / installIntegration.
Keep onNext handlers that collect pre-OAuth inputs synchronous with the next user click. Calling setPreOptions from that second click is a new gesture, so the OAuth popup that follows it is still allowed.
3. Surface the error instead of spinning
OAuthBlockedError is thrown so you can replace an infinite spinner with a retry message.