Web SDK

The Tiro.health Web SDK provides native Web Components for integrating FHIR-based form filling capabilities into any web application.

The SDK is built with native Web Components that work with any JavaScript framework or vanilla JavaScript:

  • <tiro-form-filler>: Interactive form rendering with full SDC support
  • <tiro-narrative>: Clinical narrative generation from responses
  • <tiro-validation-report>: Real-time validation error display

Installation

Choose one of the following installation methods:

CDN (Recommended for Quick Start)

The fastest way to get started. No build tools required - just add two lines to your HTML. Ideal for proof of concepts and rapid prototyping.

<link rel="stylesheet" href="https://cdn.tiro.health/sdk/latest/tiro-web-sdk.css">
<script src="https://cdn.tiro.health/sdk/latest/tiro-web-sdk.iife.js"></script>

NPM

For production applications with build tools:

npm install @tiro-health/web-sdk

Import the SDK and its stylesheet:

import '@tiro-health/web-sdk'
import '@tiro-health/web-sdk/style.css'

Bundle Options

BundleImportUse When
Full@tiro-health/web-sdkYour app doesn't use React
Lite@tiro-health/web-sdk/liteYour app already has React 18

Quick Start

<tiro-form-filler
  questionnaire="http://templates.tiro.health/example|1.0.0">
</tiro-form-filler>

This renders an interactive form based on the FHIR Questionnaire. Users can fill in fields, and the component manages all form state internally.

With Narrative and Validation

Components link together using the for attribute:

<tiro-form-filler
  id="patient-form"
  questionnaire="http://templates.tiro.health/patient-intake|2.0.0"
  sdc-endpoint-address="https://sdc.tiro.health/fhir/r5">
</tiro-form-filler>

<tiro-narrative for="patient-form"></tiro-narrative>
<tiro-validation-report for="patient-form"></tiro-validation-report>

This displays three linked components: the form, a live-updating clinical narrative generated from the responses, and validation errors that appear when required fields are missing or invalid.

Inline Questionnaire

For simple forms or testing, you can embed the questionnaire definition directly in HTML using a <script> tag with type="application/fhir+json":

<tiro-form-filler id="inline-form">
  <script type="application/fhir+json" slot="questionnaire">
    {
      "resourceType": "Questionnaire",
      "status": "draft",
      "title": "Feedback Form",
      "item": [
        {
          "linkId": "name",
          "type": "string",
          "text": "What is your name?"
        },
        {
          "linkId": "feedback",
          "type": "text",
          "text": "Any feedback?"
        }
      ]
    }
  </script>
</tiro-form-filler>

<script>
  const form = document.getElementById('inline-form')
  form.addEventListener('tiro-submit', (e) => {
    console.log('Submitted:', e.detail.response)
  })
</script>

This renders a simple two-field form with a text input and a textarea. When submitted, the FHIR QuestionnaireResponse is logged to the console.


Components

<tiro-form-filler>

The primary component for rendering FHIR Questionnaires.

Attributes:

  • questionnaire - Canonical URL with version (e.g., url|version)
  • sdc-endpoint-address - SDC FHIR server URL
  • launch-context - JSON object with FHIR resources (Patient, Encounter)
  • read-only - Disable form editing

Methods:

  • getResponse() - Get current QuestionnaireResponse
  • submit() - Programmatically submit the form
  • checkValidity() - Check if form is valid

Events:

  • tiro-ready - Fired when the questionnaire is loaded. e.detail.questionnaire
  • tiro-update - Fired on every form change. e.detail.response
  • tiro-submit - Fired when the form is submitted. e.detail.response
  • tiro-validate - Fired after validation. e.detail.isValid, e.detail.operationOutcome
  • tiro-error - Fired on errors. e.detail.error

<tiro-narrative>

Generates human-readable clinical narratives from questionnaire responses.

Attributes:

  • for - ID of the <tiro-form-filler> to link to
<tiro-narrative for="my-form"></tiro-narrative>

Events:

  • tiro-update - Fired when narrative content changes. e.detail.narrative

<tiro-validation-report>

Displays FHIR OperationOutcome validation results. Automatically hides when valid.

Attributes:

  • for - ID of the <tiro-form-filler> to link to
<tiro-validation-report for="my-form"></tiro-validation-report>

Events:

  • tiro-update - Fired when validation results change. e.detail.operationOutcome

Custom Authentication

For applications requiring custom authentication (OAuth, JWT, session tokens), create an SDCClient programmatically instead of using the sdc-endpoint-address attribute.

Basic Setup

import { SDCClient } from '@tiro-health/web-sdk'

const sdcClient = new SDCClient({
  baseUrl: 'https://sdc.example.com/fhir/r5',
  auth: async () => {
    const token = await getAccessToken() // Your auth logic
    return `Bearer ${token}`
  }
})

const form = document.querySelector('tiro-form-filler')
form.sdcClient = sdcClient

The auth function is called before each request, allowing you to handle token refresh automatically.

With Interceptors

Add request/response interceptors for logging or error handling:

const sdcClient = new SDCClient({
  baseUrl: 'https://sdc.example.com/fhir/r5',
  auth: async () => `Bearer ${await getAccessToken()}`
})

// Log outgoing requests
sdcClient.interceptors.request.use(async (req) => {
  console.log('Request:', req.method, req.url)
  return req
})

// Handle auth errors
sdcClient.interceptors.response.use(async (res) => {
  if (res.status === 401) {
    // Trigger re-authentication
  }
  return res
})

document.querySelector('tiro-form-filler').sdcClient = sdcClient

Framework Integration

Web Components work with any framework using standard DOM APIs.

React

import '@tiro-health/web-sdk'
import '@tiro-health/web-sdk/style.css'
import { useRef, useEffect } from 'react'

function FormPage() {
  const formRef = useRef(null)

  useEffect(() => {
    const form = formRef.current
    const handleSubmit = (e) => console.log(e.detail.response)
    form.addEventListener('tiro-submit', handleSubmit)
    return () => form.removeEventListener('tiro-submit', handleSubmit)
  }, [])

  return (
    <tiro-form-filler
      ref={formRef}
      questionnaire="http://example.com/q|1.0.0"
      sdc-endpoint-address="https://sdc.example.com/fhir/r5"
    />
  )
}

Angular

Add CUSTOM_ELEMENTS_SCHEMA to your module or component:

import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core'
import '@tiro-health/web-sdk'
import '@tiro-health/web-sdk/style.css'

@Component({
  selector: 'app-form',
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <tiro-form-filler
      [attr.questionnaire]="questionnaire"
      [attr.sdc-endpoint-address]="sdcEndpoint"
      (tiro-submit)="onSubmit($event)">
    </tiro-form-filler>
  `
})
export class FormComponent {
  questionnaire = 'http://example.com/q|1.0.0'
  sdcEndpoint = 'https://sdc.example.com/fhir/r5'

  onSubmit(event: CustomEvent) {
    console.log(event.detail.response)
  }
}

Vanilla JavaScript

import '@tiro-health/web-sdk'
import '@tiro-health/web-sdk/style.css'

const form = document.createElement('tiro-form-filler')
form.setAttribute('questionnaire', 'http://example.com/q|1.0.0')
form.setAttribute('sdc-endpoint-address', 'https://sdc.example.com/fhir/r5')
form.addEventListener('tiro-submit', (e) => console.log(e.detail.response))
document.body.appendChild(form)

For detailed API reference, see the npm package documentation.

Was this page helpful?