Installation
The prescription widget shares the same loader as the pre-authorization widget — you only need to include the loader script once even if you use both.
1. Include the loader
<script src="https://widgets.osigu.com/v1/loader.js" async></script>
Version-pin for production:
<script src="https://widgets.osigu.com/v1.2.0/loader.js" async></script>
2. Create a host element
<div id="osigu-rx" style="width: 720px; max-width: 100%;"></div>
3. Mount
<script>
document.addEventListener('DOMContentLoaded', async () => {
await window.osiguReady;
OsiguPrescription.mount({
container: '#osigu-rx',
getToken: async () => {
const res = await fetch('/api/osigu/token', { credentials: 'include' });
const { access_token } = await res.json();
return access_token;
},
environment: 'sandbox',
locale: 'en',
// Optional: prefill an existing patient
prefill: {
patientId: 'pat_01HXE...',
},
onComplete: (outcome) => {
console.log('Prescription issued:', outcome.prescription_code);
},
onError: (err) => console.error(err),
onClose: () => console.log('user closed the widget'),
});
});
</script>
That's the whole integration.
React wrapper
import { useEffect, useRef } from 'react';
export function PrescriptionWidget({ patientId, onComplete }) {
const ref = useRef(null);
useEffect(() => {
let handle;
window.osiguReady.then(() => {
handle = window.OsiguPrescription.mount({
container: ref.current,
getToken: async () => (await fetch('/api/osigu/token')).json().then(j => j.access_token),
environment: 'sandbox',
prefill: patientId ? { patientId } : undefined,
onComplete,
});
});
return () => handle?.unmount();
}, [patientId, onComplete]);
return <div ref={ref} />;
}
Vue 3 wrapper
<script setup>
import { ref, onMounted, onBeforeUnmount, defineProps, defineEmits } from 'vue';
const props = defineProps({ patientId: String });
const emit = defineEmits(['complete']);
const host = ref(null);
let handle;
onMounted(async () => {
await window.osiguReady;
handle = window.OsiguPrescription.mount({
container: host.value,
getToken: async () => (await fetch('/api/osigu/token')).json().then(j => j.access_token),
environment: 'sandbox',
prefill: props.patientId ? { patientId: props.patientId } : undefined,
onComplete: (o) => emit('complete', o),
});
});
onBeforeUnmount(() => handle?.unmount());
</script>
<template><div ref="host" /></template>
Token proxy
Same as the pre-auth widget — never put OAuth secrets in the browser. Your server exchanges client_id / client_secret and hands the browser the access_token. See Obtaining tokens.
Unmounting
Call handle.unmount() when the doctor closes the prescription flow or the surrounding component unmounts. This releases the state and detaches DOM listeners.
Content Security Policy
If you have a strict CSP, allow:
script-src https://widgets.osigu.comconnect-src https://widgets.osigu.com https://sandbox.osigu.com(orhttps://api.osigu.comin prod)img-src https://widgets.osigu.com data:
The prescription widget doesn't render any iframes (no OTP challenge in the prescription flow), so you don't need to whitelist frame-src for this widget.
Both widgets on the same page
If you're loading both the pre-auth and prescription widgets on the same page, you can mount them independently — they don't share state, and the loader is a single script tag. Both use different top-level namespaces (OsiguPreAuth vs OsiguPrescription) to avoid collisions.
Next steps
- Configuration — the option list.
- Events — outcome payloads.