WidgetsPatient portal

Patient portal widget

window.MedosPatientPortal — a returning patient verifies once and manages their own appointments, family members, and session credits.

Where the booking widget ends at "you're booked", the patient portal starts there. A returning patient verifies a phone number or email address once, and sees everything the clinic already holds for that contact.

<script src="https://widgets.medos.one/v2/portal.js"></script>
<div id="medos-portal"></div>
<script>
  MedosPatientPortal.init({
    apiKey: "mk_your_publishable_key",
    mode: "inline",
    containerId: "medos-portal",
  });
</script>

The bundle is self-contained and exposes one global, window.MedosPatientPortal. Install › CDN covers deferring the tag and loading it on demand.

What the patient sees

Sign in — a phone number or an email address, then the code sent to it. The same verification the booking widget uses; the otpChannels option controls which channels are offered.

Their appointments — upcoming and past, with a picker to switch between the family members registered on that contact.

Act on one — view the details, cancel it, reschedule it to another slot, or submit a payment claim if the clinic takes manual payments.

Session credits — a wallet card showing active session packs, how many sessions remain on each, and when they expire.

Family members — the patient records already registered on that contact, plus a dialog to add another.

Book again — opens the booking widget in place, skipping verification because this patient has already proved the contact.

Try it

Configure it below and copy the snippet. The preview runs against a demo workspace.

Patient portal

A returning patient verifies once, then manages their own appointments and credits.

window.MedosPatientPortal

Theme

Custom theme

View

Verification

Which channels the patient can receive their one-time code on. Narrow it when a workspace only supports one — an email option with no sending domain configured never delivers.

Live preview
index.html
<div id="medos-portal" style="min-height: 600px"></div>

<script src="https://widgets.medos.one/v2/portal.js"></script>

<script>
  MedosPatientPortal.init({
    apiKey: "mk_your_publishable_key",
    mode: "inline",
    containerId: "medos-portal",
    theme: "default",
    onError: (err) => console.error(err),
  });
</script>

init({ mode: "modal" }) opens the modal straight away, so call it from the click handler rather than on page load. After the first click, open() shows the same portal again.

<script defer src="https://widgets.medos.one/v2/portal.js"></script>
<button id="my-appointments">My appointments</button>
<script>
  let started = false;
  document.getElementById("my-appointments").onclick = () => {
    if (started) return MedosPatientPortal.open();
    started = true;
    MedosPatientPortal.init({
      apiKey: "mk_your_publishable_key",
      mode: "modal",
      onClose: () => console.log("Portal closed"),
    });
  };
</script>

In this section

Notes

  • The portal is patient-scoped, not doctor-scoped. It shows the appointments on the verified contact across every doctor in the workspace. There is nothing to pre-select.
  • Nothing is visible before verification. The first screen is the contact field; no patient data is fetched until a code has been confirmed.
  • A portal and a booking widget can share a page. Each gets its own store and query client, so verifying in one does not sign the other in.
  • Language and direction are per-instance. The portal has its own language selector, and applies right-to-left direction to its own root only — never to your page. See Internationalization.

On this page