Photon Elements are a set of prebuilt UI-components that can be used to add prescribing functionality into any web-based clinical tool.

Elements are built using WebComponent technology and can be used in any frontend app - regardless of framework. Elements do not use outdated iframe technology!

Elements automatically handle authentication and ensure that only authorized prescribers can send prescriptions. The UI is designed to be responsive across various screen sizes and can be easily styled.

1708

This UI can be embedded directly in your clinical app.

<photon-client 
  id="YOUR_CLIENT_ID"
  org="YOUR_ORG_ID"
>
  <photon-prescribe-workflow/>
</photon-client>

Get Started

First install our elements package from NPM:

npm i @photonhealth/elements

If using a framework like React, you'll need to dynamically import the package. This will register the custom elements with the browser's CustomElementRegistry.

import("@photonhealth/elements")

You can also import within head tag in HTML:

<script src="https://cdn.rx.dev/elements/@latest/dist/index.js" type="module"></script>

Client Element

Next, add the photon-client element toward the top level of your application.

<photon-client
  id="your_client_id"
  org="your_org_id"
  redirect-uri="https://localhost:3000"
  dev-mode="true"
>
  <!-- nested photon elements -->
</photon-client>
PropertyDescription
idThe public ID registered to your application (with whitelisted URLs)
orgThe Photon organization ID associated with your account
auto-loginOptional, defaults to "false". Set this to auto-login="true" to trigger automatically login on page load if the user is unauthenticated
redirect-uriOptional. Specifies where to redirect the user after a successful login. This cannot include a pathname, so for example it should look like https://example.com rather than https://example.com/user/1234/prescribe. You can however incorporate a strategy that handles a query parameter such as https://example.com?redirect=user%2F1234%2Fprescribe.

When working locally, set the port to 3000 for authentication to work.
redirect-pathOptional. Helper that reroutes to a pathname after logging in returns the user to the redirect URI. An example redirect path is user/1234/prescribe. This will only work if the photon-client element exists at the redirect-uri base path.
dev-modeOptional. When working locally set this to "true"in order to point our service at our staging service neutron rather than our production services at photon

These values can be found in the settings page of the Photon App, or in the Sandbox App. All photon- elements must be contained within the photon-client to function correctly.

If you're unable to put the photon-client at the root of your domain, then the property redirect-path will not work. However you can pass a query parameter to the redirect-uri property such as https://localhost:3000?redirect=user/1234 and then handle the redirect with your own application logic.

Check out our example repo that shows how to handle the authentication redirect. The main branch shows how to use a query string to redirect and the root branch shows how to use the photon-client at root with the redirect-path.

Prescribe Element

The photon-prescribe-workflow can be added anywhere within the photon-client and renders a basic prescribe workflow. It accepts the following props:

PropertyDescription
patient-idID of the patient receiving the prescription
template-idsTemplates that should be pre-selected
template-overridesWhen adding template-ids this attribute allows for overriding specific fields on the template. The overrides are a mapping where the keys are template IDs and the values are the override specifications.

<photon-prescribe-workflow template-ids="tmp_01H5JB37PPK9F64RE3QQ52WD7M,tmp_01GQJDV39GPEJ03BATZV1X0SRJ" template-overrides='{"tmp_01H5JB37PPK9F64RE3QQ52WD7M": {"instructions": "these instructions are overriding the previous instructions", "fillsAllowed": 200}}' />
prescription-idsPrescriptions that should be pre-selected
enable-orderBoolean that enables the creation of an order at the same time as a prescription. When this flag is set with nothing else, a pharmacy selection card will default to a "Local Pickup" option.
enable-send-to-patientPrerequisite enable-order set to true .

Boolean that allows prescribers to send patients the option to set their own pharmacy.
enable-local-pickupPrerequisite enable-order set to true .

Boolean that allows prescribers to set the patient's pharmacy for them.
mail-order-idsPrerequisite enable-order set to true.

Comma separated list of mail order pharmacy ids.
pharmacy-idPrerequisite enable-order set to true .

Sets a preselected pharmacy.
hide-templatesOptional boolean, defaults to false. Setting this flag to true will remove the ability for providers to save personal templates.
addressOptional, setting address will override the prescriber's ability to manually set the the patient's address when enable-order is set to true. The address object to be passed takes this shape:

{ city: string; postalCode: string; state: string; street1: string; street2?: string; country?: string; }

Please note that web components accept attributes as strings. Therefore, when passing an object as a prop, you must stringify it first. Here's an example of how to pass the address object to a web component: address={JSON.stringify(address)}
external-order-idOptional ID that can be associated with the order being created.
enable-med-historyOptional Boolean, enables a card in the prescribe flow that shows the selected patient's recent prescriptions.
enable-combine-and-duplicateOptional Boolean, enables a recent orders card that shows prescriptions recently sent. If they seem to be duplicate, we'll notify the prescriber. Also, if the order hasn't been sent to a pharmacy yet we'll attempt to combine the orders into a single order to make for better patient communication.

Here's an example of a Photon Element that enables orders to a preselected pharmacy:

<photon-prescribe-workflow
  patient-id="pat_9876zyxw"
  enable-order="true"
  pharmacy-id="phr_1234abcd"
/>

Alternatively, here's how you would enable an prescribe element with all of the pharmacy selection options:

<photon-prescribe-workflow
  patient-id="pat_01GQ0XFBHSH3YXN936A2D2SD7Y"
  enable-order="true"
  enable-send-to-patient="true"
  enable-local-pickup="true"
  mail-order-ids="phr_01GA9HPVBVJ0E65P819FD881N0"
/>
The above code will enable a similar Pharmacy Select card.

The above code will enable a similar Pharmacy Select card.

Events

Event payloads will be on detail.

document.addEventListener('photon-order-created', (e) => {
  console.log('Order Info: ', e.detail.order);
});
Event NameDescriptionDetail
photon-prescriptions-createdTriggered when prescriptions have been successfully created.{ prescriptions: Prescription[] }
photon-order-createdIf the enable-order flag is set and the prescriber selects to "Send Order", this will trigger when prescriptions and an order are successfully created.{ order: Order }
photon-prescriptions-errorTriggered when there are errors creating prescriptions.{ errors: GraphQLError[] }
photon-order-errorTriggered when there are errors creating the order.{ errors: GraphQLError[] }
photon-order-combinedTriggered when a draft prescription has been combined into an existing order.{ orderId }

Framework Support

Below you'll find example integrations for React, Angular, and Vue.

import("@photonhealth/elements").catch(() => {});
import { createRef, useEffect, useState } from "react";

function App() {
  const photonPrescribeRef = createRef();

  useEffect(() => {
    const log = () => {
      console.log("treatment prescribed!");
    }
    if (photonPrescribeRef.current) {
      photonPrescribeRef.current.addEventListener("photon-prescribe-success", log);
      const removal = () => photonPrescribeRef.current.removeEventListener("photon-prescribe-success", log);
      return () => removal()
    }
  }, [])

  return (
    <div>
      <photon-client
        id="CLIENT_ID"
        org="ORGANIZATION_ID"
      >
         <photon-prescribe-workflow ref={photonPrescribeRef} />
      </photon-client>
    </div>
  );
}

export default App;
import { Component } from '@angular/core';
import('@photonhealth/webcomponents').catch(() => {});

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'my-app';

  public log() {
    console.log("treatment prescribed!");
  }
}

...

<div>
  <photon-client
      id="CLIENT_ID"
      org="ORGANIZATION_ID"
    >
      <photon-prescribe-workflow (photon-prescribe-success)="log()"></photon-prescribe-workflow>
    </photon-client>
</div>
<script setup lang="ts">
import("@photonhealth/webcomponents").catch((err) => {});

const log = () => {
  console.log("treatment prescribed!");
}
</script>

<template>
  <div>
    <photon-client
      id="CLIENT_ID"
      org="ORGANIZATION_ID"
    >
      <photon-prescribe-workflow v-on:photon-prescribe-success="log()" />
    </photon-client>
  </div>
</template>