Symptoms
The surface shows "Continue" instead of the flow
The surface shows "Continue" instead of the flow
You see a Continue button where the flow should be.Cause. The package could not confirm that this browser will run the flow in a frame. The possible reasons:
- The launching page’s origin is not registered against your embed key, or the key is unknown or revoked. The console shows a frame-ancestors violation.
- The browser refused the flow’s cookie in a frame.
- Your page’s Content Security Policy blocks the connect origin from being framed.
- The probe frame never answered in time: a blocked request, a frame that never loaded, or a slow network.
- The check passed, but the flow’s iframe loaded and never reported it was ready, usually because the connect origin refused to be framed. The button appears about eight seconds after that iframe loads.
- This page already probed once with no answer. The verdict is kept until the page reloads.
www and the apex are different origins. Registered origins must be https, or http on localhost.When the policy is the cause, allow the origin of your invitation URL in frame-src. If your policy has no frame-src, use child-src, and if it has neither, use default-src. The cookie probe is a frame on the same origin and falls under the same directive. The package makes no requests of its own, so no other directive needs to change.A refused cookie decides within one round trip. A probe frame that loads and never answers, including on an unregistered origin, waits about six seconds after it loads before the button appears, and one that never loads at all waits up to eight. The flow’s own iframe waits eight seconds after it loads, as in the last cause above. Only the policy and origin cases show in the browser console, as a violation report. A refused cookie or an unanswered frame on a registered origin leaves nothing there.See the three modes.A provider's sign-in window is blocked
A provider's sign-in window is blocked
The flow shows a message saying the sign-in window was blocked.Cause. Popups are not allowed on the launching page. The flow stays up with the form intact, and nothing fires until the setting allows the window.Fix. Allow popups on the launching page.See the provider window.
No callback ever arrives
No callback ever arrives
The flow runs, but none of your callbacks fire.Cause. Most often the launching page’s origin is not registered against your embed key, or the key is unknown or revoked. The two look the same from your page. The flow falls back to the popup and runs there, but its messages are addressed elsewhere, or for an unknown or revoked key not sent at all. The other causes:
- A window or link you opened yourself used
noopener. The package never opens withnoopener. - The launching page sends
Cross-Origin-Opener-Policy: same-origin, which severs the popup. - The flow ran in the tab and no page called
resume(). - The destination page is on another origin.
- The user left.
onClose arrives the moment the popup opens
onClose arrives the moment the popup opens
You press Continue, the popup opens, and
onClose arrives straight away with no outcome. The user carries on in the window.Cause. The launching page sends Cross-Origin-Opener-Policy: same-origin, which disconnects it from the popup as soon as the popup loads the flow. From your page the window looks closed. The console shows a warning from the package naming the header.Fix. Serve the launching page with same-origin-allow-popups instead. It keeps the popup connected and changes nothing else.See When you receive nothing.The surface closes right after it opens
The surface closes right after it opens
The flow appears and
onExit arrives at once, followed by onClose, with reason set to invalid_invitation or invitation_unavailable.Cause. The flow could not load the invitation in the link. Behind the callbacks the flow shows an error screen, which goes away when you take the surface down on onClose.Fix. For invalid_invitation, check the invitation you launched with and create a new link. For invitation_unavailable, offer a retry, since the link may be fine. Show the user your own message either way.See onExit when the invite link never loaded.open() throws
open() throws
Calling
open() throws an error and nothing renders.Cause. open() throws a TypeError if the invitation URL does not parse, is not http or https, or is http on any host other than localhost, 127.0.0.1 or [::1]. It also throws if it is called before <body> exists with no container, or outside a browser.Fix. Pass an https invitation URL. Plain http is accepted on localhost, 127.0.0.1 and [::1] only. Call open() in a browser, after <body> exists or with a container.See open().resume() fires on a page the flow did not return to
resume() fires on a page the flow did not return to
A
resume() callback fires on a page the user reached some other way.Cause. A redirected launch left this tab within the last 30 minutes and was abandoned, and resume() consumed its record.Fix. Call resume() on the two destination pages and nowhere else.See resume() and When you receive nothing.The flow renders but your branding is ignored
The flow renders but your branding is ignored
The flow appears with your account’s branding instead of the color or logos you passed.Cause. One of these:
- The embed key does not resolve to a registered, active key.
brandColor,brandSecondary,logoUrlandlogoUrlDarkare dropped and the branding configured on your account applies. - A value was rejected.
brandColorandbrandSecondarymust contain exactly six hex digits, with an optional leading#, and logo URLs must be absolutehttps. - A logo failed to load. That leaves its slot empty.
- You passed
variant: "card". The logo then shows only on the consent card.
A second launch does nothing
A second launch does nothing
Calling
open() again does not start a new flow.Cause. One flow runs at a time. The call brought the live launch back and returned its handle: the popup window if one is open, otherwise the overlay. In a container it does nothing visible.Fix. Let the live flow end, or call destroy() on its handle, before launching again.See one flow at a time.When you receive nothing
Each of these is a real outcome, not an error to surface. Your connection webhooks remain the record. The absence of a callback is never proof that nothing happened.- Unregistered origin. The page you embed from is not registered against your embed key. The flow falls back to the popup and runs, but every message is addressed elsewhere and the browser drops it. This is the origin check doing its job.
- Unknown or revoked embed key. This is deliberately indistinguishable from an unregistered origin. The flow falls back to the popup and runs, and sends no messages at all. You cannot tell the two apart, and neither can an attacker.
- Severed opener. Opening the flow through a window or link of your own with
noopenerremoves the channel the completion travels on. The user still finishes. The package never opens withnoopener. Cross-Origin-Opener-Policy: same-originon the launching page. In the popup mode, the browser cuts your page off from the window as soon as it loads the flow. From your page the window looks closed, so you getonClosewith no outcome shortly after the click, while the user carries on in a window your page cannot hear or close. If your invitation has redirect URLs, the flow then finishes by sending that window to one of them. Without them it stays on its last screen. The package logs a console warning when a window closes this fast. Serve the page withsame-origin-allow-popupsinstead.- Redirect mode with no
resume()call. The flow completed in your tab and nothing was listening when it came back. - A
resume()destination on another origin. The outcome crosses the navigation in asessionStoragerecord, and that is partitioned by origin as well as by tab. Both destination pages must be on the same origin as the page that launched, orresume()emits nothing. - The user abandoned the surface. No terminal event was produced because the flow never reached one. In a frame, a user who connects and never presses Done produces
onConnectionbut noonSuccess. The connection is real.