Configure the patient portal
Every MedosPatientPortal option with its type and default, the init, open and close methods, and the PatientPortalConfig TypeScript type.
The portal takes the same config object as the booking widget, so theming, sizing, and verification behave identically. Want to try options before writing code? Use the playground.
Methods
init(config)
MedosPatientPortal.init(config: PatientPortalConfig): voidStarts the portal. Call it once per page.
- Inline mode — mounts into the element named by
containerId. - Modal mode — opens the modal immediately, so call it from a click handler rather than on page load.
Required: apiKey. Plus containerId when mode is "inline".
open(config?)
MedosPatientPortal.open(config?: Partial<PatientPortalConfig>): voidOpens the portal as a modal again after init(), merging the argument into
the last-known config. Throws if no apiKey has ever been set. Call init()
first: it is what exchanges your key for a session.
close()
MedosPatientPortal.close(): voidCloses the open modal and fires onClose
if one was provided. A no-op when the portal is inline or the modal is already
closed.
Options
Core
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | Yes | — | Your Medos publishable key. See API keys. |
mode | "modal" | "inline" | No | "inline" | Anything other than "modal" is treated as inline. |
containerId | string | For inline | — | DOM id the portal mounts into. Ignored in modal mode. |
Sizing
| Option | Type | Default | Description |
|---|---|---|---|
maxWidth | number | string | 720px | Cap the width. A number means px. |
maxHeight | number | string | — | Cap the height; inner content scrolls. |
Verification
| Option | Type | Default | Description |
|---|---|---|---|
otpChannels | ("phone" | "email")[] | ["phone", "email"] | Which channels the sign-in step offers. |
The same rules as the booking widget: the order does not matter, and a value
that isn't a usable array falls back to ["phone"] alone rather than to both.
Appearance
| Option | Type | Default | Description |
|---|---|---|---|
theme | "default" | "modern" | MedosTheme | PartialTheme | "default" | Built-in name, full theme object, or partial override. See Theming. |
primaryColor | string | From theme | Brand colour. Hover and active shades are derived automatically. |
secondaryColor | string | From theme | Secondary brand colour. |
borderRadius | string | number | From theme | Corner radius. A number means px. |
fontFamily | string | From theme | CSS font stack applied across the portal. |
fontUrl | string | — | Stylesheet URL (e.g. Google Fonts) loaded so fontFamily resolves. |
fontSize | "small" | "medium" | "large" | "medium" | Scales every font size proportionally. |
Callbacks
onError and onClose. onSuccess is accepted but never called. See
Callbacks.
Accepted but ignored
The portal inherits the booking widget's config type, so these keys type-check and are silently ignored rather than rejected:
externalMemberId, calendarOnly, compact, layout, doctorInfo,
doctorInfoByDoctorId.
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, which is why the booking-scope options have no effect here.
PatientPortalConfig type
interface PatientPortalConfig {
/** Required. Your publishable key. */
apiKey: string;
// mounting
mode?: "modal" | "inline";
containerId?: string;
maxWidth?: number | string;
maxHeight?: number | string;
// verification
otpChannels?: ("phone" | "email")[];
// appearance
theme?: "default" | "modern" | MedosTheme | PartialTheme;
primaryColor?: string;
secondaryColor?: string;
borderRadius?: string | number;
fontFamily?: string;
fontUrl?: string;
fontSize?: "small" | "medium" | "large";
// callbacks
onError?: (error: Error) => void;
onClose?: () => void;
/** Accepted for config compatibility with the booking widget, never called. */
onSuccess?: (result: unknown) => void;
}Booking-scope keys (externalMemberId, calendarOnly, compact, layout,
doctorInfo, doctorInfoByDoctorId) are part of the shared type and accepted
here, but have no effect.
Patient portal widget
window.MedosPatientPortal — a returning patient verifies once and manages their own appointments, family members, and session credits.
Patient portal callbacks
The callbacks MedosPatientPortal fires — onError when it can't start, onClose when the modal closes — and why onSuccess is never called.