The customer hosts the player themselves: a container div and loader.min.js, which injects the bundle into this page. Materially different for identity, and the difference is not subtle.
| Player runs on | this page’s own origin — first-party, in the customer’s document |
|---|---|
| Config comes from | data-* attributes only. standAlone() never runs, so query params are not read |
| Sign-in transport | iframe on the Resi origin, nested in a first-party page |
| This page can read the viewer id | yes — unavoidably; see below |
<div id="resi-video-player" data-embed-id="…" data-type="event" data-autoplay="false" data-identify-viewer="required"></div> <script src="https://control.jefflowery.dev/webplayer/loader.min.js"></script>
data-resi-body, so isInOwnFrame() is false and standAlone() is skipped. The mode switch above sets data-identify-viewer directly rather than passing a query param.postMessage target from the origin of the window running the player — which here is the customer’s. So the result is delivered to this page.Every postMessage delivered to this window, newest last, with repeats collapsed. In this case:
[VIEWER ID] line after signing in, from control.jefflowery.dev. On this page only, that is the design. It is also the only place in these six where you can read the message the flow actually sends.page.min.js here, so no PING_PLAYER and no handshake.
Messages tagged [this page] come from this document’s own origin and are hidden by default.
They are browser extensions: password managers, React DevTools and the like all inject content scripts that
post on this page’s behalf. Nothing from the player or the sign-in page can appear under that tag.