The three modes
You do not choose a mode. The outcome (onSuccess or onExit) and onClose arrive on all three, so one set of handlers covers every path. The exception is the redirect mode. It navigates away from the page holding your callbacks, and resume() delivers only the outcome you declare, followed by onClose.
1
Iframe
The surface renders immediately with a brief loading state while the package checks whether this browser will run the flow in an iframe. If it will, the iframe mounts in the surface behind that loading state, which stays up until the flow reports it is ready (the same message that becomes
onOpen). If that report has not come eight seconds after the iframe’s page loads, the package removes the iframe and falls back to the popup, because the usual cause is a browser refusing to render the flow in an iframe. No warm-up call, no popup, no user gesture needed.2
Popup
The flow needs a cookie in a cross-site context, and not every browser will send one. Where the iframe check fails, or the iframe never reports it is ready, the surface shows a Continue button instead, and clicking it opens the flow in a popup window. One extra click, only where the iframe cannot carry the flow.
3
Redirect
If the browser blocks the popup too, the flow navigates the browser tab your page is in to the connect origin and runs there, full-page. Your page and its callbacks are gone. If your invitation has redirect URLs, the flow returns to one of them, and
resume() on that page delivers the outcome. Without them the flow stays on its last screen, and your webhooks are the only record. See The redirect path.A launching page inside a frame never takes this path. The tab is not its to navigate, so the surface stays where it is and asks the user to allow pop-ups and press Continue again.The redirect mode carries the launch across the navigation in
sessionStorage. If storage is disabled, full, or throws on access, there is nothing for resume() to find, and it emits neither the outcome nor onClose. The flow still completes and your webhooks still fire. Only the callbacks are lost. A launch is never held back because its record could not be written.The provider window
Some providers (Samsara and Motive among them) sign the fleet in on their own site, and that step cannot run inside an iframe. In the iframe and popup modes, pressing Connect on one of those providers opens a second window from the connect origin. The provider’s login runs there, and the flow closes the window once the surface you launched confirms it has the connection. That holds even if the user reloaded or navigated the surface while the window was open. If no confirmation arrives, the window tells the user they are connected instead of closing. The surface you launched stays where it is and shows the new connection. That window belongs to the Catena app, not to the package and not to you. It is opened from the user’s click and closed when it is done. The provider’s pages never get a reference to your page, because the window’s opener is the Catena document. You cannot observe it and do not need to.onConnection arrives from the surface you launched, the same as for a provider that takes credentials.
Two things to plan for:
- Popups must be allowed on the launching page. A kiosk or managed browser that blocks them everywhere leaves the user on a message saying the sign-in window was blocked, with the form intact to try again once the setting allows it. Nothing navigates and no callback fires.
- This is not the popup mode. The popup mode opens the whole flow in a window because the browser refused the iframe. The provider window opens inside a flow that is already running, and only for a provider that signs in on its own site.
The redirect path
In the redirect mode the flow leaves your page, so nothing on it can receive a callback. When the user finishes, the flow navigates to thesuccess_redirect_url or the failure_redirect_url on your invitation, and the resume() call on that page delivers the outcome and onClose. onOpen, onConnection and onConnectionDeleted never arrive on this path. resume() always gives an empty connectionIds, and takes reason from the URL’s skip_reason or status. The flow appends other query parameters to the redirect URL too, so read them if you need them. The failure page also receives integration requests, with status=integration-requested, the ending that arrives as onExit in the other modes. Your connection webhooks are the record, as they are on every path.
The redirect URLs are optional. Only the redirect path relies on them. A popup whose launching page has closed or navigated away also falls back to them. Otherwise, in the iframe and popup modes the flow reports its outcome by message. Without them the redirect path still completes, but the user stays on the flow’s last screen, whether it succeeded or not, with no way back to your site. If the browser blocks the popup shows both pages and the query parameters.