Skip to main content
This guide shows how to integrate SofIA SDK in applications using native JavaScript without additional frameworks.

Initial setup

1. Installation

npm install @omniloy/sofia-sdk

2. Component import

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SofIA SDK - Vanilla JS</title>
    
    <!-- Import component -->
    <script type="module">
        import '@omniloy/sofia-sdk';
    </script>
</head>
<body>
    <!-- Component will be available here -->
</body>
</html>

Basic implementation

HTML structure

<div id="sofia-container">
    <!-- language="en" for English UI, default is "es" (Spanish) -->
    <sofia-sdk
        id="sofia"
        baseurl="https://api.example.com/v1"
        wssurl="wss://ws.example.com"
        apikey="sk-your-api-key-here"
        userid="user_12345"
        patientid="patient_67890"
        templateid="clinical-notes-v1"
        language="en"
        isopen="false"
        showconsentindicator="true"
        template='{
            "$schema": "http://json-schema.org/draft-07/schema#",
            "title": "clinical_notes",
            "type": "object",
            "required": ["diagnosis"],
            "properties": {
                "diagnosis": {"type": "string", "description": "Main diagnosis"}
            }
        }'
    ></sofia-sdk>
    
    <button id="toggle-sofia">Open/Close SofIA</button>
</div>

JavaScript configuration

// Wait for component to be defined
customElements.whenDefined('sofia-sdk').then(() => {
    const sofiaComponent = document.getElementById('sofia');
    const toggleButton = document.getElementById('toggle-sofia');
    
    // Configure callback to receive reports
    sofiaComponent.handleReport = (report) => {
        console.log('Clinical report received:', report);
        
        // Process report according to your needs
        displayReport(report);
        sendToEHR(report);
    };
    
    // Configure callback for visibility changes
    sofiaComponent.setIsOpen = (isOpen) => {
        console.log('Component state:', isOpen ? 'Open' : 'Closed');
        sofiaComponent.isopen = isOpen;
        toggleButton.textContent = isOpen ? 'Close SofIA' : 'Open SofIA';
    };
    
    // Handle button click
    toggleButton.addEventListener('click', () => {
        const currentState = sofiaComponent.getAttribute('isopen') === 'true';
        sofiaComponent.setAttribute('isopen', String(!currentState));
    });
});

// Function to display report in interface
function displayReport(report) {
    const reportContainer = document.getElementById('report-display');
    if (reportContainer) {
        const heading = document.createElement('h3');
        heading.textContent = 'Clinical Report';
        const pre = document.createElement('pre');
        pre.textContent = JSON.stringify(report, null, 2);
        reportContainer.replaceChildren(heading, pre);
    }
}

// Function to send to EHR/HIS system
function sendToEHR(report) {
    // Implement integration with your system
    fetch('/api/clinical-reports', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(report)
    }).then(response => {
        console.log('Report sent to EHR:', response.status);
    }).catch(error => {
        console.error('Error sending report:', error);
    });
}

Retrieving the last report

Use the set-get-last-report callback to access the last generated report for the current patient/user session. The SDK provides a function that returns a Promise resolving to the stored report (or undefined if none exists).
sofiaComponent.setGetLastReport = (getLastReportFn) => {
    // Store the function for later use
    window.getLastSofiaReport = getLastReportFn;
};

// Later, retrieve the last report
async function fetchLastReport() {
    const report = await window.getLastSofiaReport();
    if (report) {
        console.log('Last report:', report);
    }
}
Add debug="true" to the <sofia-sdk> element to enable verbose console logging. This is helpful during development to trace SDK lifecycle events, connection status, and configuration validation.
<sofia-sdk debug="true" ...></sofia-sdk>

State management

Visibility control

const sofiaComponent = document.querySelector('sofia-sdk');

// Open programmatically
function openSofia() {
    sofiaComponent.isopen = true;
}

// Close programmatically  
function closeSofia() {
    sofiaComponent.isopen = false;
}

// Toggle state
function toggleSofia() {
    const isCurrentlyOpen = sofiaComponent.getAttribute('isopen') === 'true';
    sofiaComponent.setAttribute('isopen', String(!isCurrentlyOpen));
}

Patient data update

// Update patient information
function updatePatientData(newPatientId, patientInfo) {
    sofiaComponent.patientid = newPatientId;
    sofiaComponent.patientdata = JSON.stringify(patientInfo);
}

// Usage example
updatePatientData('patient_98765', {
    fullName: 'Jane Doe',
    birthDate: '1979-03-15',
    extraData: {
        medical_practice: 'Internal Medicine',
        allergies: ['Penicillin'],
        chronic_conditions: ['Type 2 diabetes', 'Hypertension']
    }
});
See Patient Data for the complete data structure reference.

Error handling

The SDK logs all errors to the browser console with the [Sofia SDK] prefix. Enable debug="true" to see detailed error output. Handle errors in your callbacks with standard try/catch:
sofiaComponent.handleReport = (report) => {
    try {
        // Process the report
        sendToEHR(report);
    } catch (error) {
        console.error('Error processing report:', error);
        // Show fallback UI to the user
    }
};
For a complete list of error messages and their resolution steps, see the Error Reference.

Complete example

For a complete and functional implementation, check our GitHub example: View complete Vanilla TypeScript example → The example includes:
  • Complete project setup
  • Advanced state management
  • Integration with mocked APIs
  • Robust error handling
  • Custom CSS styling

Component lifecycle

Adding the component

Wait for the custom element to be defined before configuring callbacks:
customElements.whenDefined('sofia-sdk').then(() => {
  const sofia = document.querySelector('sofia-sdk');
  sofia.handleReport = handleReport;
});

Removing the component (SPA cleanup)

If your application dynamically adds and removes SofIA (e.g., client-side routing), remove the element from the DOM when navigating away:
function destroySofia() {
  const sofia = document.querySelector('sofia-sdk');
  if (sofia) {
    sofia.remove();
  }
}
The SDK cleans up internal resources (WebSocket connections, audio streams) automatically when the element is disconnected from the DOM.

Additional considerations

Performance

  • The component initializes lazily to optimize loading time
  • Use customElements.whenDefined() to avoid race conditions

Security

  • Never expose your apikey in client code in production
  • Implement server-side validation for all reports
  • Always use HTTPS for all communications

Next steps

  1. React integration
  2. Angular integration
  3. Required properties reference
  4. Optional properties reference