The v1 module
What the first-generation widget is, what it still supports, and how it differs from Saphere Scan v2.
New integrations should use Saphere Scan v2. This section exists for products already running the v1 module in production, and documents it as it is.
The v1 module, called rjcaducy internally, is the original embeddable widget. It is a React application, bundled into a single file and served from the CDN, that renders the whole measurement journey inside a container you provide.
It remains served and it remains functional. It is no longer where new work happens.
What it does
The same thing v2 does, by a different route: it explains the measurement, collects consent, guides the user into frame, captures for thirty seconds, and shows a result. It reports progress to your page through an onEvent callback.
It is customisable through a large options object — an eleven-colour palette, per-screen toggles, and a complete override of every string in ten languages.
How it differs from v2
The two widgets do not share an API. Migrating means rewriting the integration, not renaming a few fields.
v1 (Handler) | v2 (SaphereScan) | |
|---|---|---|
| Entry point | window.Handler, or the handler-ready event | import SaphereScan from … |
| Mounting | Handler.load(container, options) | SaphereScan.create(root, options) then await bootstrap() |
| Credential | Your API key, or a measure id you fetch yourself | A short-lived, scoped access token |
| Events | 8 event types | 40, namespaced domain:event |
| Refusing a transition | onEvent returning false | A separate hooks API, with a guard delay |
| Colours | 11 numbered slots (color01…color11) | Per-screen and per-variable options |
| Isolation | Optional shadow DOM (useShadow) | Always a shadow root |
Two differences matter more than the rest.
The credential model changed. In v1 you either put an API key where the widget could reach it, or you created the measure yourself and handed the widget its identifier. In v2 the widget asks your server for a token that is scoped to one thing, expires within 48 hours, and can be made single-use. That is the main reason to migrate.
The event channel does not block. In v1, the widget waited for your onEvent handler, and a returned false cancelled a screen change. A slow handler could therefore hold the interface. v2 never waits on onEvent; the power to refuse moved to hooks, where it is bounded by a timeout.