Skip to main content
These practices apply to every Proview SDK module. Module-specific guidance lives on each module’s own page.

Loading

Load the loader script once per page load. The loader attaches itself as window.Proview. Injecting it a second time — on a client-side route change, for example — can duplicate listeners and re-run initialization. Guard the injection with a check for window.Proview. Define window.proviewOnLoad before the loader tag. The SDK fires it as soon as it is ready, and Proview.init() belongs inside it. If you assign the callback after the loader tag, the SDK may have already fired and your callback will never run. Handle a failed script load. A CDN failure is otherwise silent:

Initialization

Declare dsn and credential once. They are set on Proview.init() and inherited by every module in the modules array. Do not repeat them per module. Declare only the modules you use. Each factory in modules pulls in its own runtime.
Always await init and check the result. Proview.init() resolves to a boolean. Using a module before it resolves is a race:

Credentials

Fetch tokens as late as possible. Tokens are short-lived. One embedded in server-rendered HTML may already be expired by the time the user acts. Have your backend fetch it at bootstrap time instead. Never hard-code credentials in client source. The DSN identifies the project and is safe to ship; the credential is not. Plan for expiry. Long assessments outlive most token lifetimes. Decide up front whether your integration refreshes the token or fails closed, and make that behaviour visible to the user.

Error handling

When errors thrown by callback functions are not handled by the parent application, Proview swallows them to prevent disruption of the SDK’s core functionality. Always implement proper error handling inside your callbacks.
Register one global handler, early. Proview.onError supports a single handler — registering a new one replaces the previous. Register it before Proview.init() so initialization failures are captured, and fan out from inside it if several parts of your app need to react.
Handle errors inside callbacks too. A throw inside your own callback is swallowed by the SDK, so it will not reach the global handler:
Respect type. critical means core functionality is impacted and the user needs to know. warning and info should be logged, not surfaced. Severity is set per occurrence, so read type on every error rather than assuming a fixed severity per code.

Mount targets

Make sure the container exists before you mount. Mount targets are resolved at call time, so the element must already be in the DOM. In a component framework, mount from the effect that runs after render, not during it. Give the container explicit dimensions. A container with no height renders nothing visible. Either size it with CSS or pass explicit dimensions to the module.

Monitoring your integration

Log every SDK error to your own monitoring system, tagged with the DSN, environment, and the user or attempt identifier. Console logs are not available to you when a customer reports a problem in production. Capture the error code, not just the message. On validation failures also capture validationErrors.formattedMessage — it names the fields that were rejected.