npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@meetelise/hc-scheduler-widget

v1.2.4

Published

Healthcare scheduler widget

Readme

@meetelise/hc-scheduler-widget

An embeddable healthcare scheduling widget powered by EliseAI. Adds a modal-based appointment scheduler to any website with a single script tag.

Installation

Add the following script tag to your page:

<script type="module">
  import HCScheduler from "https://cdn.eliseai.com/@meetelise/hc-scheduler-widget";

  HCScheduler.start({
    organizationId: "your-organization-id",
  });
</script>

This loads the widget, registers the eliseAi.hc global API, and makes the scheduling modal available on your page.

Quick Start

<button onclick="eliseAi.hc.openScheduling()">Schedule an Appointment</button>

<script type="module">
  import HCScheduler from "https://cdn.eliseai.com/@meetelise/hc-scheduler-widget";

  HCScheduler.start({
    organizationId: "your-organization-id",
  });
</script>

That's it — clicking the button opens the scheduling modal.

Configuration

HCScheduler.start() accepts the following options:

| Option | Type | Required | Description | | ---------------- | -------- | -------- | --------------------------------------------------------- | | organizationId | string | Yes | Your EliseAI organization ID. | | utm_source | string | No | Default UTM source applied to all scheduling sessions. | | utm_medium | string | No | Default UTM medium applied to all scheduling sessions. | | utm_campaign | string | No | Default UTM campaign applied to all scheduling sessions. | | utm_term | string | No | Default UTM term applied to all scheduling sessions. | | utm_content | string | No | Default UTM content applied to all scheduling sessions. |

Example with UTM defaults

<script type="module">
  import HCScheduler from "https://cdn.eliseai.com/@meetelise/hc-scheduler-widget";

  HCScheduler.start({
    organizationId: "your-organization-id",
    utm_source: "website",
    utm_medium: "referral",
    utm_campaign: "spring-promo",
    utm_term: "obgyn",
    utm_content: "homepage-hero",
  });
</script>

API

Once HCScheduler.start() has been called, the global eliseAi.hc object exposes:

eliseAi.hc.openScheduling(options?)

Opens the scheduling modal. Can be called with no arguments or with an options object:

| Option | Type | Description | | ---------------- | -------- | ----------------------------------------------------------------------------------------- | | organizationId | string | Overrides the widget-level organizationId for this session. | | providerId | string | Opens scheduling pre-filtered to a specific provider. | | locationId | string | Opens scheduling pre-filtered to a specific location. | | utm_source | string | UTM source for this session. Overrides the widget-level utm_source if provided. | | utm_medium | string | UTM medium for this session. Overrides the widget-level utm_medium if provided. | | utm_campaign | string | UTM campaign for this session. Overrides the widget-level utm_campaign if provided. | | utm_term | string | UTM term for this session. Overrides the widget-level utm_term if provided. | | utm_content | string | UTM content for this session. Overrides the widget-level utm_content if provided. |

eliseAi.hc.close()

Closes the scheduling modal programmatically.

Provider & Location Pages

You can create provider-specific or location-specific booking buttons by passing providerId or locationId to openScheduling():

<!-- Provider-specific booking -->
<button onclick="eliseAi.hc.openScheduling({ providerId: '1' })">
  Book with Dr. Stiles
</button>

<!-- Location-specific booking -->
<button onclick="eliseAi.hc.openScheduling({ locationId: '1' })">
  Book at Irving
</button>

<!-- Both provider and location -->
<button
  onclick="eliseAi.hc.openScheduling({ providerId: '22', locationId: '55' })"
>
  Book with Dr. Riley at Irving
</button>

UTM Tracking

UTM parameters are passed through to the scheduling URL so you can track where appointments originate.

How UTM values flow

  1. Widget-level defaults — Set any combination of utm_source, utm_medium, utm_campaign, utm_term, and utm_content in HCScheduler.start(). These apply to every openScheduling() call.
  2. Per-call overrides — Pass any of those same parameters to openScheduling(). These take priority over the widget-level defaults.

Parsing UTM from the page URL

A common pattern is to read UTM parameters from the current page's URL and pass them into the widget:

<script type="module">
  import HCScheduler from "https://cdn.eliseai.com/@meetelise/hc-scheduler-widget";

  const params = new URLSearchParams(window.location.search);

  HCScheduler.start({
    organizationId: "your-organization-id",
    utm_source: params.get("utm_source") || undefined,
    utm_medium: params.get("utm_medium") || undefined,
    utm_campaign: params.get("utm_campaign") || undefined,
    utm_term: params.get("utm_term") || undefined,
    utm_content: params.get("utm_content") || undefined,
  });
</script>

With this setup, visiting https://yoursite.com?utm_source=google&utm_medium=cpc&utm_campaign=spring&utm_term=obgyn&utm_content=ad-123 will automatically pass those values through to the scheduler.

Important: Cookie-stored UTM values

If your site stores UTM parameters in cookies (e.g. capturing them on first visit and persisting them across pages), the widget will not read those cookies automatically. You are responsible for reading the cookie values yourself and passing them to the widget explicitly:

<script type="module">
  import HCScheduler from "https://cdn.eliseai.com/@meetelise/hc-scheduler-widget";

  // Example: read UTM values from your own cookies
  function getCookie(name) {
    const match = document.cookie.match(
      new RegExp("(^| )" + name + "=([^;]+)"),
    );
    return match ? decodeURIComponent(match[2]) : undefined;
  }

  const params = new URLSearchParams(window.location.search);

  HCScheduler.start({
    organizationId: "your-organization-id",
    utm_source: params.get("utm_source") || getCookie("utm_source"),
    utm_medium: params.get("utm_medium") || getCookie("utm_medium"),
    utm_campaign: params.get("utm_campaign") || getCookie("utm_campaign"),
    utm_term: params.get("utm_term") || getCookie("utm_term"),
    utm_content: params.get("utm_content") || getCookie("utm_content"),
  });
</script>

The widget operates inside an iframe on a different domain and cannot access your site's cookies. Always pass UTM values through the JavaScript API.

Google Tag Manager (GTM) Events

The scheduling iframe emits postMessage events to the parent window that can be forwarded to GTM's dataLayer. Add the following script to your page to listen for these events and push them into the data layer:

<script>
  const GTM_POST_MESSAGE_TYPE = "elise-gtm-event";

  function isGtmPostMessage(message) {
    return (
      message !== null &&
      typeof message === "object" &&
      message.type === GTM_POST_MESSAGE_TYPE &&
      typeof message.event === "string" &&
      message.properties !== null &&
      typeof message.properties === "object"
    );
  }

  function handleGtmMessage(e) {
    if (!isGtmPostMessage(e.data)) return;

    const { event, properties } = e.data;

    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({ event, ...properties });
  }

  window.addEventListener("message", handleGtmMessage);
</script>

GTM Events

| Event | Payload | Description | | ---------------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | | patientTypeSelected | { patientType: "newPatient" \| "existingPatient" } | User selects new or existing patient on the welcome page | | phoneNumberSubmitted | — | New patient submits their phone number for verification | | verificationCodeResent | — | User requests a new verification code to be sent | | verificationCodeSubmitted | — | User submits their phone verification code | | chatMessageSent | — | User sends a message in the AI triage chat | | appointmentTypeSelected | — | Chat AI determines an appointment type and user clicks the schedule button | | personalDetailsUpdated | — | New patient submits their personal details (name, DOB, address, etc.) | | insuranceUpdated | — | Existing patient updates their insurance during the confirm details step | | continuedWithSelfPay | — | Patient elects to continue with self-pay after insurance ineligibility | | patientTransferred | { reason: string } | Patient is transferred out of the scheduling flow. Reasons include: "noAvailability", "workflow", or an EligibilityCheckReason value (e.g., "NOT_ACCEPTED", "UNKNOWN") | | bookingSucceeded | — | Appointment(s) successfully booked | | upcomingRescheduleInitiated| { appointmentIds: string[] } | Existing patient initiates rescheduling from the snapshot page | | upcomingRescheduleSucceeded| — | Rescheduled appointment(s) successfully confirmed | | upcomingAppointmentCanceled| { appointmentIds: string[] } | Existing patient cancels upcoming appointment(s) | | upcomingAppointmentConfirmed| { appointmentIds: string[] } | Existing patient confirms upcoming appointment(s) |

Behavior

  • Modal sizing — On screens wider than 600px, the modal appears centered with a max size of 900×900px. On smaller screens, it expands to fullscreen.
  • Closing — Users can close the modal by pressing Escape or clicking the × button.
  • Font — The widget automatically loads the Inter font if it isn't already present on the page.