Focus Chat Element
The <focus-chat> custom element is the main component for embedding AI chat functionality into your web pages.
Element Definition
<focus-chat
agent_card_url="https://agent.example.com/card.json"
config='{"greeting": "Hello!"}'
>
</focus-chat>
Attributes
agent_card_url (Required)
Type: String
Purpose: URL to the agent card JSON configuration file
The agent card defines your AI assistant's profile, capabilities, and endpoint information.
Example:
<focus-chat agent_card_url="https://api.example.com/agent-card.json">
Requirements:
- Must be a valid HTTPS URL
- Must return valid JSON
- Must include proper CORS headers
config (Optional)
Type: String (JSON) or CSS Selector
Purpose: Configuration parameters for the chat widget
Default: {}
JSON String Format
<focus-chat
agent_card_url="..."
config='{"greeting": "Hello!", "title": "Inhotel Chat Assistant"}'
>
Script Reference Format
<script id="chat-config" type="application/json">
{"greeting": "Hello from script!", "title": "Inhotel Chat Assistant"}
</script>
<focus-chat
agent_card_url="..."
config="#chat-config"
>
Element Lifecycle
1. Registration
The custom element is automatically registered when the Focus Chat script loads:
customElements.define('focus-chat', FocusChatElement);
2. Initialization
When the element is added to the DOM:
- Attribute Parsing: Reads
agent_card_urlandconfigattributes - Shadow DOM Creation: Creates isolated DOM tree
- Agent Card Loading: Fetches agent configuration
- UI Rendering: Builds chat interface
- Event Binding: Attaches interaction handlers
3. Ready State
Element is ready when:
- Agent card successfully loaded
- UI components rendered
- Event listeners attached
DOM Structure
The element creates a Shadow DOM with this structure:
<focus-chat>
#shadow-root
<div class="ih-container">
<div class="ih-trigger">
<!-- Floating chat trigger button -->
</div>
<div class="ih-popup" style="display: none;">
<div class="ih-header">
<!-- Title, avatar, and close button -->
</div>
<div class="ih-body">
<!-- Message list, system messages, streaming responses -->
</div>
<div class="ih-input">
<!-- Textarea, send button -->
</div>
</div>
</div>
</focus-chat>
CSS Styling
Shadow DOM Isolation
The widget uses Shadow DOM for complete style isolation. External CSS cannot affect the widget's appearance.
Configuration-Based Styling
All styling is controlled through configuration parameters:
<focus-chat
config='{
"header_background_color": "#3b82f6",
"font_family": "Inter, sans-serif"
}'
>
CSS Custom Properties
The widget supports CSS variables for dynamic theming:
<style>
:root {
--ih-header-bg: #3b82f6;
--ih-user-message-bg: #f0f0f0;
--ih-assistant-message-bg: #ffffff;
--ih-font-family: "Inter", sans-serif;
}
</style>
<focus-chat
config='{"header_background_color": "var(--brand-color)"}'
>
JavaScript API
Element Properties
agentCardUrl
Get/set the agent card URL:
const widget = document.querySelector('focus-chat');
console.log(widget.agentCardUrl);
widget.agentCardUrl = 'https://new-agent.example.com/card.json';
config
Get/set the configuration:
const widget = document.querySelector('focus-chat');
console.log(widget.config);
widget.config = {"greeting": "New greeting!"};
Element Methods
reload()
Reload the widget with current configuration:
const widget = document.querySelector('focus-chat');
widget.reload();
openChat()
Programmatically open the chat popup:
const widget = document.querySelector('focus-chat');
widget.openChat();
closeChat()
Programmatically close the chat popup:
const widget = document.querySelector('focus-chat');
widget.closeChat();
sendMessage(message)
Send a message programmatically:
const widget = document.querySelector('focus-chat');
widget.sendMessage('Hello from JavaScript!');
Error Handling
Common Error Types
-
Agent Card Loading Failed
{
type: 'agent-card-error',
message: 'Failed to load agent card',
url: 'https://agent.example.com/card.json'
} -
Configuration Error
{
type: 'config-error',
message: 'Invalid JSON configuration',
config: '{"invalid": json}'
} -
Network Error
{
type: 'network-error',
message: 'Failed to send message',
endpoint: 'https://api.example.com/chat'
}
Browser Compatibility
Supported Browsers
- Chrome 54+: Full support
- Firefox 63+: Full support
- Safari 10.1+: Full support
- Edge 79+: Full support
Polyfill Requirements
For older browsers, include Web Components polyfills:
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2/webcomponents-loader.js"></script>
<script src="https://embed.agents.inhotel.io/focus-chat/latest/focus-chat.min.js"></script>
Feature Detection
Check for custom element support:
if ('customElements' in window) {
// Focus Chat supported
console.log('Custom elements supported');
} else {
// Provide fallback
console.log('Custom elements not supported');
}
Performance Characteristics
Loading Performance
- Script Size: ~50KB minified
- Initialization: <100ms typical
- Memory Usage: ~2MB baseline
Runtime Performance
- Message Rendering: <16ms per message
- Streaming Updates: 60fps smooth
- Memory Growth: Minimal with history limits
Advanced Usage
Multiple Instances
Multiple widgets on the same page:
<!-- Product support -->
<focus-chat
agent_card_url="https://product.example.com/agent.json"
config='{"source_context": ".product-info"}'
>
</focus-chat>
<!-- General support -->
<focus-chat
agent_card_url="https://support.example.com/agent.json"
config='{"source_context": ".help-section"}'
>
</focus-chat>
Dynamic Configuration
Update configuration at runtime:
const widget = document.querySelector('focus-chat');
const newConfig = {
greeting: 'Updated greeting!',
header_background_color: '#10b981'
};
widget.config = JSON.stringify(newConfig);
widget.reload();
Next Steps
- Learn about configuration parameters
- Check browser support details