Widgets

Analytics and tracking

Send Medos widget events to GA4, Google Tag Manager and Mixpanel from the callbacks, which widget fires what, and how to keep personal data out.

The widgets don't ship their own analytics — you own the data. Send events from their callbacks to whichever tool you use.

WidgetConversion eventOther events
BookingonSuccess — a completed bookingonError, onClose
Enquiry formonSuccess — a filed enquiryonError, onClose
Patient portalNone — it has no completion eventonError, onClose
Package purchaseNone — onComplete is a button handler, not a sale—

The recipes below use the booking widget.

Read the payload shape first

Every recipe below reports the conversion from onSuccess. The token number lives inside result.queueToken — a top-level result.tokenNumber is always undefined, so a recipe copied from an older version of this page silently records null for every queue booking.

GA4 (gtag)

MedosBooking.init({
  apiKey: "mk_...",
  onSuccess: (result) => {
    gtag("event", "generate_lead", {
      event_category: "medos_booking",
      appointment_id: result.appointmentId ?? null,
      token_number: result.queueToken?.tokenNumber ?? null,
      payment_method: result.paymentMethod?.kind ?? null,
    });
  },
  onError: (err) => {
    gtag("event", "medos_booking_error", {
      error_message: err.message,
    });
  },
});

Google Tag Manager

Push events onto dataLayer and let GTM handle routing:

MedosBooking.init({
  apiKey: "mk_...",
  onSuccess: (result) => {
    window.dataLayer?.push({
      event: "medos_booking_success",
      appointmentId: result.appointmentId ?? null,
      tokenNumber: result.queueToken?.tokenNumber ?? null,
      paymentMethod: result.paymentMethod?.kind ?? null,
    });
  },
});

Mixpanel

MedosBooking.init({
  apiKey: "mk_...",
  onSuccess: (result) => {
    mixpanel.track("Booking Completed", {
      appointmentId: result.appointmentId ?? null,
      tokenNumber: result.queueToken?.tokenNumber ?? null,
      paymentMethod: result.paymentMethod?.kind ?? null,
    });
  },
  onError: (err) => {
    mixpanel.track("Booking Error", { message: err.message });
  },
});

Tracking the full funnel

Step-by-step funnel events — patient entered a contact, verified a code, picked a slot — aren't exposed. What you can collect from the widget is the two ends of the funnel: onSuccess for a completed booking, and onClose for a modal that was dismissed. Everything in between needs platform-side instrumentation, so talk to the platform team if you need it.

The enquiry form

The enquiry form has its own onSuccess, which fires with the submitted form values rather than a server id. It's a useful second conversion event — just don't forward the payload itself, which is all personal data:

MedosEnquiry.init({
  apiKey: "mk_...",
  mode: "inline",
  containerId: "medos-enquiry",
  onSuccess: () => window.dataLayer?.push({ event: "medos_enquiry_submitted" }),
});

Don't send PII

Never send patient names, phone numbers, or emails to third-party analytics without explicit consent — GA4 and Mixpanel both prohibit PII in event properties. Stick to booking IDs, token numbers, and the payment method. result.queueToken.patientName is PII: don't pass the token object through wholesale.

On this page