> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praxis-ai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK Examples

> Runnable examples for the Praxis AI Web SDK — the live SDK Playground and a complete PriaTestHarness API class you can adapt for your own application.

These examples accompany the [JavaScript SDK](/mdx/sdk/javascript) reference. Use them to see a complete, working integration end to end — from loading the SDK and detecting connection, to sending commands in response to user actions.

## SDK Playground Example

You can take a look at a running example at [SDK Playground Example](https://pria.praxislxp.com/pria-sdk-web-sample.html).

```
https://pria.praxislxp.com/pria-sdk-web-sample.html
```

<img src="https://mintcdn.com/praxisai/kykHd4cobeHLACGX/images/sdk/websdk-playground.jpg?fit=max&auto=format&n=kykHd4cobeHLACGX&q=85&s=773248be55101ce3bfc784de3cd1c310" alt="SDK Playground Example" width="1086" height="853" data-path="images/sdk/websdk-playground.jpg" />

This example demonstrates how to cleanly initialize the integration, detects when sucessfully connected, execute specific commands; such as starting conversation, listing favorites, conversations or assistants, posting a new message, and more.

## API Class Example

This example is provided AS IS to demonstrate how you can cleanly integrate a Digital Twin in your Web Application and sendvarious commands programatically in response to user actions on the page. It is extracted from the playground example code.

```javascript theme={null}
/**
* Pria SDK Test Harness Application
* Enhanced version with modern JavaScript patterns and professional UI
*/
class PriaTestHarness {
    constructor() {
        this.pria = null;
        this.waitForPriaTimer = null;
        this.uiDisplayed = false;
        this.isConnected = false;
        
        // Configuration
        this.config = {
            displayOptions: {
                buttonPositionRight: 'calc(50% - 40px)',
                buttonPositionBottom: '80px'
            },
            instanceConfig: {
                publicIdguest: '41407647-248c-4f0e-a317-71fc151ba8fb', 
                publicId: 'f831501f-b645-481a-9cbb-331509aaf8c1',
                pictureUrl: 'https://ca.slack-edge.com/T08Q47N2NUT-U08PZ8CUVDK-d32d2c5679ad-512'
            },
            userConfig: {
                email: 'alex@praxis-ai.com',
                profilename: 'Alex Lebegue',
                usertype: 1,
                userid: 110,
                roleid: 123,               
                rolename: "Course ABC",
                partnerid: 1,              
                partnername: "ABC Global Inc." 
            },
            conversation: {
                id: 777,
                name: "My Conversation"
            }
        };
        
        this.init();
    }
    
    /**
    * Initialize the application
    */
    async init() {
        try {
            await this.loadPriaSDK();
            this.bindEventListeners();
            this.showToast('Application initialized successfully', 'success');
        } catch (error) {
            console.error('Failed to initialize application:', error);
            this.showToast('Failed to initialize application', 'error');
        }
    }
    
    /**
    * Load the Pria SDK
    */
    loadPriaSDK() {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = 'pria-sdk-web.js';
            script.async = true;
            
            script.onload = () => {
                console.log('Web SDK Script loaded');

                const url = 'https://pria.praxislxp.com';
                
                PriaIntegration.loadSdk(
                    url, 
                    this.config.displayOptions, 
                    this.config.instanceConfig, 
                    this.config.userConfig
                );
                
                this.waitForPriaTimer = setInterval(() => this.waitForPria(), 2000);
                resolve();
            };
            
            script.onerror = (error) => {
                console.error('Failed to load Web SDK:', error);
                reject(new Error('Web SDK loading failed'));
            };
            
            document.body.appendChild(script);
        });
    }
    
    /**
    * Wait for Pria to be available and set up subscriptions
    */
    waitForPria() {
        if (!window.pria) {
            console.log("Waiting for Pria to load...");
            return;
        }
        
        // console.log('Pria loaded:', JSON.stringify(window.pria.priaObj, null, 2));
        
        clearInterval(this.waitForPriaTimer);
        this.pria = window.pria;
        this.isConnected = true;
        
        this.updateConnectionStatus(true);
        this.pria.subscribe(this.handlePriaResponse.bind(this));
        this.showToast('Connected to Pria SDK', 'success');

        window.addEventListener('beforeunload', () => {
            this.pria.unsubscribe(handleResponse)
        })
    }
    
    /**
    * Handle responses from Pria
    */
    handlePriaResponse(response) {
        console.log("Response from Pria:", JSON.stringify(response, null, 2));
        this.displayResponse(response);
        this.hideLoading();
    }
    
    /**
    * Bind event listeners to UI elements
    */
    bindEventListeners() {
        // Message sending
        document.getElementById('send-message-btn').addEventListener('click', () => {
            this.sendMessage();
        });
        
        // Quick actions
        document.getElementById('start-conversation-btn').addEventListener('click', () => {
            this.startConversation();
        });
        
        document.getElementById('stop-conversation-btn').addEventListener('click', () => {
            this.stopConversation();
        });
        
        document.getElementById('get-assistants-btn').addEventListener('click', () => {
            this.getAssistants();
        });
        
        document.getElementById('get-conversations-btn').addEventListener('click', () => {
            this.getConversations();
        });
        
        document.getElementById('get-favorites-btn').addEventListener('click', () => {
            this.getFavorites();
        });
        
        // Toggle Pria visibility
        document.getElementById('toggle-pria-btn').addEventListener('click', () => {
            this.togglePriaVisibility();
        });
        
        // Clear response
        document.getElementById('clear-response-btn').addEventListener('click', () => {
            this.clearResponse();
        });
        
        // Enter key support for message input
        document.getElementById('message-input').addEventListener('keydown', (e) => {
            if (e.ctrlKey && e.key === 'Enter') {
                this.sendMessage();
            }
        });
    }
    
    /**
    * Send a message to Pria
    */
    sendMessage() {
        if (!this.ensurePriaConnection()) return;
        
        const message = document.getElementById('message-input').value.trim();
        const assistantId = document.getElementById('assistant-id-input').value.trim();
        
        if (!message) {
            this.showToast('Please enter a message', 'warning');
            return;
        }
        
        if (!assistantId) {
            this.showToast('Please enter an assistant ID', 'warning');
            return;
        }
        
        this.showLoading();
        this.clearResponse();
        
        const request = {
            command: 'message.post',
            inputs: [message],
            assistantId: assistantId,
            selectedCourse: {
                course_id: this.config.conversation.id,
                course_name: this.config.conversation.name
            }
        };
        
        this.pria.send(request);
        this.showPria();
        this.showToast('Message sent', 'info');
    }
    
    /**
    * Start a conversation
    */
    startConversation() {
        if (!this.ensurePriaConnection()) return;
        
        this.showLoading();
        this.clearResponse();
        
        const request = {
            command: 'convo.start',
            assistantId: '674e9fd3d7e18aa82eb49fda',
            selectedCourse: {
                course_id: 22345,
                course_name: 'Conversational Assist'
            }
        };
        
        this.pria.send(request);
        this.showPria();
        this.showToast('Starting conversation', 'info');
    }
    
    /**
    * Stop a conversation
    */
    stopConversation() {
        if (!this.ensurePriaConnection()) return;
        
        const request = {
            command: 'convo.stop'
        };
        
        this.pria.send(request);
        this.showToast('Conversation stopped', 'info');
    }
    
    /**
    * Get list of assistants
    */
    getAssistants() {
        if (!this.ensurePriaConnection()) return;
        
        this.showLoading();
        this.clearResponse();
        
        const request = {
            command: 'assistants.list'
        };
        
        this.pria.send(request);
        this.showToast('Fetching assistants', 'info');
    }
    
    /**
    * Get list of conversations
    */
    getConversations() {
        if (!this.ensurePriaConnection()) return;
        
        this.showLoading();
        this.clearResponse();
        
        const request = {
            command: 'conversations.list'
        };
        
        this.pria.send(request);
        this.showToast('Fetching conversations', 'info');
    }
    
    /**
    * Get list of favorites
    */
    getFavorites() {
        if (!this.ensurePriaConnection()) return;
        
        this.showLoading();
        this.clearResponse();
        
        const request = {
            command: 'favorites.list'
        };
        
        this.pria.send(request);
        this.showToast('Fetching favorites', 'info');
    }
    
    
    /**
    * Toggle Pria visibility
    */
    togglePriaVisibility() {
        if (!this.ensurePriaConnection()) return;
        
        this.uiDisplayed = !this.uiDisplayed;
        this.pria.display(this.uiDisplayed);
        
        const btn = document.getElementById('toggle-pria-btn');
        const icon = btn.querySelector('i');
        const text = btn.querySelector('span');
        
        if (this.uiDisplayed) {
            icon.className = 'fas fa-eye-slash';
            text.textContent = 'Hide Pria';
            this.showToast('Pria UI shown', 'info');
        } else {
            icon.className = 'fas fa-eye';
            text.textContent = 'Show Pria';
            this.showToast('Pria UI hidden', 'info');
        }
    }
    
    /**
    * Show Pria interface
    */
    showPria() {
        if (this.pria && !this.uiDisplayed) {
            this.pria.display(true)
            this.uiDisplayed = true;
        }
    }
    
    /**
    * Display response in the viewer
    */
    displayResponse(data) {
        const viewer = document.getElementById('response-viewer');
        viewer.value = data ? JSON.stringify(data, null, 2) : '';
    }
    
    /**
    * Clear the response viewer
    */
    clearResponse() {
        document.getElementById('response-viewer').value = '';
    }
    
    /**
    * Show loading indicator
    */
    showLoading() {
        document.getElementById('loading-indicator').classList.remove('hidden');
    }
    
    /**
    * Hide loading indicator
    */
    hideLoading() {
        document.getElementById('loading-indicator').classList.add('hidden');
    }
    
    /**
    * Update connection status indicator
    */
    updateConnectionStatus(connected) {
        const statusElement = document.getElementById('connection-status');
        const dot = statusElement.querySelector('div');
        const text = statusElement.querySelector('span');
        
        if (connected) {
            dot.className = 'w-3 h-3 bg-green-500 rounded-full';
            text.textContent = 'Connected';
            text.className = 'text-sm text-green-600';
        } else {
            dot.className = 'w-3 h-3 bg-red-500 rounded-full animate-pulse';
            text.textContent = 'Disconnected';
            text.className = 'text-sm text-red-600';
        }
    }
    
    /**
    * Ensure Pria connection exists
    */
    ensurePriaConnection() {
        if (!this.pria || !this.isConnected) {
            this.showToast('Pria SDK not connected', 'error');
            return false;
        }
        return true;
    }
    
    /**
    * Show toast notification
    */
    showToast(message, type = 'info') {
        const container = document.getElementById('toast-container');
        const toast = document.createElement('div');
        
        const colors = {
            success: 'bg-green-500',
            error: 'bg-red-500',
            warning: 'bg-yellow-500',
            info: 'bg-blue-500'
        };
        
        const icons = {
            success: 'fas fa-check-circle',
            error: 'fas fa-exclamation-circle',
            warning: 'fas fa-exclamation-triangle',
            info: 'fas fa-info-circle'
        };
        
        toast.className = `${colors[type]} text-white px-6 py-3 rounded-lg shadow-lg flex items-center space-x-3 transform transition-all duration-300 translate-x-full`;
        toast.innerHTML = `
            <i class="${icons[type]}"></i>
            <span>${message}</span>
        `;
        
        container.appendChild(toast);
        
        // Animate in
        setTimeout(() => {
            toast.classList.remove('translate-x-full');
        }, 100);
        
        // Auto remove
        setTimeout(() => {
            toast.classList.add('translate-x-full');
            setTimeout(() => {
                if (container.contains(toast)) {
                    container.removeChild(toast);
                }
            }, 300);
        }, 3000);
    }
}

// Initialize the application when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    new PriaTestHarness();
});
```

## Related

* [JavaScript SDK](/mdx/sdk/javascript) — full SDK reference: commands, responses, and UI control methods
* [SDK Object Definitions](/mdx/sdk/object-definitions) — request/response object schemas
* [Web App Integration](/mdx/integrations/web/introduction) — embedding Pria in a web application
