FHIR Platform Suite — Setup & Deployment Guide

Complete guide to deploying the Client and Vendor platforms on GitHub Pages and running a live FHIR R4 order → result message flow between them.

✓ No server required FHIR R4 compliant GitHub Pages free tier

What you're deploying

Five files. Two platforms. One shared messaging bridge — all running in the browser with no backend.

client.html

Clinician-facing order platform. Create ServiceRequests via form, JSON, or XML. View returned results and download files.

vendor.html

Lab/radiology-facing portal. Receive orders, build DiagnosticReport results, attach files, send back to client.

fhir-bridge.js

Shared messaging layer. BroadcastChannel for real-time tab-to-tab delivery. localStorage for persistence and file storage.

index.html

Landing page with bridge status, order/result counters, and links to both platforms. Your deployment's home page.

Repository layout

All five files go in the root of your repository. No subfolders needed.

fhir-platform/ ← your GitHub repository ├── index.html ← landing page (GitHub Pages serves this first) ├── client.html ← client platform ├── vendor.html ← vendor platform ├── fhir-bridge.js ← shared bridge (loaded by both HTML files) ├── .nojekyll ← tells GitHub Pages to skip Jekyll processing └── README.md ← documentation (optional)
⚠️ All five files must be in the same folder. The bridge script is referenced as src="fhir-bridge.js" (relative path). If you rename any file, update the references inside the HTML files too.

How messages flow between platforms

Client Tab
client.html
──►
fhir-bridge.js
submitOrder()
──►
localStorage
fhir_orders
──►
BroadcastChannel
fhir_orders_channel
──►
Vendor Tab
vendor.html
Order flow: Client → Vendor (ServiceRequest)
Vendor Tab
vendor.html
──►
fhir-bridge.js
sendResult()
──►
localStorage
fhir_results
──►
BroadcastChannel
fhir_results_channel
──►
Client Tab
client.html
Result flow: Vendor → Client (DiagnosticReport Bundle)
MechanismWhat it doesLatency
BroadcastChannelInstant message delivery between same-browser tabs< 100ms
localStorage pollFallback — tabs check for new data every 4 seconds≤ 4s
storage eventCross-tab notification when localStorage changes< 200ms

1Create a GitHub Repository

You need a free GitHub account and a new public repository.

a

Sign in at github.com

Go to github.com. Create a free account if you don't have one.

b

Click the + icon → "New repository"

Top-right corner of any GitHub page. Or go directly to github.com/new.

c

Configure the repository

Fill in these fields exactly:

Repository namefhir-platform (or any name — it becomes part of your URL)
VisibilityPublic — required for free GitHub Pages
Initialize repository❌ Leave unchecked — you'll upload files manually
d

Click "Create repository"

You'll land on an empty repository page. Keep this tab open for Step 2.

2Upload Your Files

Option A — Web Upload (no Git needed, recommended)

1

Click "uploading an existing file"

On the empty repository page, look for the text "…or upload an existing file" and click it.

2

Drag and drop all 5 files at once

Drag these files from your Downloads folder into the upload box simultaneously:

index.html client.html vendor.html fhir-bridge.js .nojekyll
3

Commit the files

Scroll down, add the message Initial release, and click Commit changes.

Option B — Git Command Line

# 1. Clone your empty repository
git clone https://github.com/YOUR_USERNAME/fhir-platform.git
cd fhir-platform

# 2. Copy your 5 downloaded files into this folder, then:
git add index.html client.html vendor.html fhir-bridge.js .nojekyll README.md
git commit -m "Initial release — FHIR Platform Suite"
git push origin main
ℹ️ Replace YOUR_USERNAME with your actual GitHub username. The repository URL appears on your repository page.

3Enable GitHub Pages

1

Open repository Settings

In your repository, click the Settings tab in the top navigation bar (the gear icon).

2

Find Pages in the left sidebar

Scroll down in the left sidebar until you see Pages under the "Code and automation" section. Click it.

3

Configure the source

SourceDeploy from a branch
Branchmain
Folder/ (root)

Click Save.

4

Wait ~60 seconds, then refresh

GitHub will display a green box with your live URL:

https://YOUR_USERNAME.github.io/fhir-platform/
GitHub Pages redeploys automatically every time you push a change. There's no build step — your HTML/JS files are served directly.

4Verify Deployment

Open your Pages URL. You should see:

Landing page loads at /

The landing page (index.html) shows both platform cards and green bridge status indicators.

Both platform links open

Clicking "Open Client Platform" loads /client.html and "Open Vendor Platform" loads /vendor.html — each in a new tab.

Storage stats update

The counters on the landing page (Orders: 0, Results: 0, Files: 0) are live. After sending a test order they'll increment.


Test the complete message flow

Do this in the same browser on the same device. Open both platform tabs first.

1

Open both tabs

From the landing page, click both platform cards. Each opens in a new tab. Keep both open — don't close them.

2

Send an order from Client

In the Client tab: fill in the order form (patient name, test, priority) → click Send Order. The form builds a FHIR ServiceRequest and submits it via the bridge.

3

Watch the order arrive in Vendor

Switch to the Vendor tab. Within 1–4 seconds the order appears at the top of the Inbox with the patient name, test, and priority — colour-coded by urgency. A toast notification pops up.

4

Accept and build a result

Click Accept on the order. Go to Report Builder. The patient and order details are pre-filled. Enter lab values (e.g. Troponin 2.84 ng/mL, flag HH), optionally attach a PDF or image, then click Send Result.

5

Result arrives in Client Observations

Switch back to the Client tab. Go to Observations. The DiagnosticReport card appears with a result table, abnormal flags highlighted in red, and download buttons for every attachment.

6

Check order status updated

In Client, go to Order List. The status badge for your order has changed from SentAcceptedComplete automatically.

Downloading files on both sides

ButtonPlatformWhat downloadsFormat
↓ FHIR JSON (Order List)ClientServiceRequest resource.json · application/fhir+json
↓ FHIR JSON (Observations)ClientDiagnosticReport Bundle.json · application/fhir+json
↓ [filename] (Observations)ClientAttached file from vendorOriginal file type (PDF, JPEG, etc.)
↓ FHIR (Sent Results)VendorDiagnosticReport Bundle.json · application/fhir+json
↓ FHIR (Inbox)VendorServiceRequest received.json · application/fhir+json
↓ [ext badge] (Sent Results)VendorAttached file by typePDF / DICOM / JPEG / HL7
ℹ️ Downloads use Blob + URL.createObjectURL() — they work completely offline and require no server. Files attached by the vendor (stored as base64 in localStorage) are decoded back to their original format on download.

Browser storage limits

File typeTypical sizeBase64 sizeNotes
FHIR ServiceRequest~2 KB~3 KBNo limit in practice
FHIR DiagnosticReport Bundle~8 KB~11 KBNo limit in practice
PDF lab report200 KB – 1 MB270 KB – 1.3 MBFine for most reports
JPEG / PNG X-Ray500 KB – 2 MB670 KB – 2.7 MBWorks well
Single DICOM file500 KB – 4 MB670 KB – 5.3 MBMax ~3–4 MB per file
CT/MRI series (300+ slices)100+ MB⚠️ Too large — use ImagingStudy URL reference instead

Total localStorage across all browsers is typically 5–10 MB. The landing page shows live usage. Click Clear All Data to reset if you hit the limit during testing.


Connecting to a real FHIR server

The bridge's localStorage layer handles real-time tab-to-tab messaging. For durable storage on a real FHIR server, use the built-in REST client in each platform:

On the Client Platform

Go to Settings → Server Config. Enter your FHIR base URL and authentication. Use the Raw Editor to POST ServiceRequests directly to the server.

On the Vendor Platform

Go to Settings → Vendor Configuration. Configure the client endpoint URL. Use the FHIR Composer to POST DiagnosticReport bundles directly.

Recommended open FHIR servers for testing

ServerURLAuth
HAPI FHIR (public)https://hapi.fhir.org/baseR4None — open access
SMART Health IThttps://r4.smarthealthit.orgNone — open access
Azure Health Data ServicesYour instance URLAzure AD Bearer token
AWS HealthLakeYour endpoint URLAWS Signature V4

Cross-device messaging

⚠️ Current limitation: BroadcastChannel and localStorage work only within a single browser session on a single device. For two different computers or mobile devices to communicate, a shared backend is needed.

Option 1 — Use a real FHIR server (recommended)

Both platforms can POST/GET from the same HAPI FHIR instance. Client sends ServiceRequest → Vendor polls for new ServiceRequests → Vendor POSTs DiagnosticReport → Client polls for results.

Option 2 — Add a WebSocket relay

Replace the BroadcastChannel calls in fhir-bridge.js with WebSocket events. A free Node.js server on Railway or Render can act as a relay in under 50 lines.

Option 3 — FHIR Subscriptions (R4B / R5)

FHIR R4B and R5 define a Subscription resource that pushes notifications via webhook or WebSocket when new resources arrive. This is the production-grade path.

// Example: replace BroadcastChannel in fhir-bridge.js with WebSocket
const ws = new WebSocket('wss://your-relay.onrender.com');

function submitOrder(fhirResource, attachmentMetas) {
  // ... existing localStorage code stays ...
  ws.send(JSON.stringify({ event: 'NEW_ORDER', envelope }));
  return envelope;
}

ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (msg.event === 'NEW_RESULT') resultCallbacks.forEach(cb => cb(msg.envelope));
};

Common issues and fixes

SymptomCauseFix
Vendor Inbox doesn't receive order Different browsers or different devices Open both tabs in the same browser window on the same machine
Order arrives after 4 seconds, not instantly BroadcastChannel not supported (Safari private mode) Normal fallback — storage event poll kicks in. Use Chrome for instant delivery
"File too large" error on attachment File exceeds localStorage capacity Compress the file, or use a URL reference for DICOM series
localStorage full warning Too many files stored across sessions Click "Clear All Data" on the landing page, then reload both platform tabs
GitHub Pages returns 404 Branch name or folder wrong, or Pages not saved Check Settings → Pages. Branch must be main (not master), folder /
GitHub Pages shows raw HTML source Missing .nojekyll file Upload the .nojekyll file to the repository root
fhir-bridge.js not found (404 in console) File not uploaded or wrong folder Confirm fhir-bridge.js is in the repository root, same level as index.html
CORS error in Raw Editor FHIR server blocks browser requests Use https://hapi.fhir.org/baseR4 which has open CORS, or configure your server's CORS headers
Observations page blank after result sent Both platforms not in the same browser Open both in the same browser. Reload Client — the poll will pick up results within 4 seconds