@telelogx/analytick-widget
v1.0.4
Published
Customizable web widget for Analytick platform
Readme
Analytick Widget
A lightweight, embeddable chat widget built with Preact and TypeScript, designed for seamless integration into any website via script tag. Features real-time messaging, internationalization, and comprehensive theming support.
🚀 Features
- Lightweight & Fast: Built with Preact for minimal bundle size (~100KB gzipped)
- Easy Integration: Simple script tag embedding with custom element API
- Real-time Messaging: WebSocket support with STOMP protocol
- Internationalization: Multi-language support with RTL layout capabilities
- Customizable Theming: CSS custom properties with multiple preset themes
- Mobile Responsive: Touch-friendly design with responsive layouts
- TypeScript: Full type safety and excellent developer experience
- Shadow DOM: Style isolation prevents CSS conflicts
- Accessibility: WCAG compliant with screen reader support
- Cross-browser: Supports all modern browsers (Chrome 60+, Firefox 63+, Safari 10.1+, Edge 79+)
📦 NPM Package Usage
If you're using a modern bundler (Webpack, Rollup, Vite, etc.), you can install the widget via NPM:
npm install analytick-widgetProgrammatic Initialization
The easiest way to use the widget in a JavaScript application is via the init function:
import { init } from 'analytick-widget';
// Initialize and automatically inject the widget into document.body
init({
orgId: 'your-organization-id',
widgetId: 'your-widget-id',
baseUrl: 'https://api.yourcompany.com',
primaryColor: '#3C5BFF' // Optional
});Framework Integration (React, Vue, etc.)
The widget provides a functional component wrapper for easy integration with React and other JSX frameworks.
import { AnalytickWidget } from '@telelogx/analytick-widget';
function MyComponent() {
return (
<AnalytickWidget
orgId="your-org-id"
widgetId="your-widget-id"
baseUrl="https://api.yourcompany.com"
primaryColor="#3C5BFF"
theme="dark"
/>
);
}Alternatively, since it's a Standard Web Component, you can use the custom element directly:
In your JSX/HTML:
<analytick-widget
org-id="your-org-id"
widget-id="your-widget-id"
base-url="https://api.yourcompany.com">
</analytick-widget>📦 Quick Start
Installation & Development
# Clone the repository
git clone <repository-url>
cd intercom-widget
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Run tests
npm test
# Format code (required before commits)
npm run formatBasic Integration
Add the widget to any website with a simple script tag:
<!DOCTYPE html>
<html>
<head>
<title>Your Website</title>
</head>
<body>
<!-- Your website content -->
<!-- Widget container -->
<analytick-widget
org-id="your-organization-id"
widget-id="your-widget-id"
base-url="https://your-api-endpoint.com">
</analytick-widget>
<!-- Widget script -->
<script src="https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js"></script>
</body>
</html>🛠️ Configuration Options
Required Attributes
| Attribute | Type | Description |
|-----------|------|-------------|
| org-id | string | Your organization identifier |
| widget-id | string | Unique widget instance identifier |
| base-url | string | API endpoint URL for WebSocket connections |
Optional Attributes
| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| theme | string | "default" | Theme preset (default, dark, intercom, slack, discord) |
| language | string | "auto" | Language code (en, es, fr, ar, he, etc.) |
| position | string | "bottom-right" | Widget position (bottom-right, bottom-left, top-right, top-left) |
| auto-open | boolean | false | Automatically open widget on page load |
| greeting-message | string | - | Custom greeting message |
| primary-color | string | - | Custom primary color (hex code) |
| rtl | boolean | false | Force right-to-left layout |
Advanced Configuration Example
<analytick-widget
org-id="org_123456789"
widget-id="widget_abcdef"
base-url="https://api.yourcompany.com"
theme="dark"
language="es"
position="bottom-left"
auto-open="true"
greeting-message="¡Hola! ¿Cómo podemos ayudarte?"
primary-color="#007bff"
rtl="false">
</analytick-widget>🎨 Theming & Customization
Built-in Themes
The widget includes several preset themes:
- default: Clean, modern design with blue accents
- dark: Dark mode with high contrast
- intercom: Intercom-inspired styling
- slack: Slack-like appearance
- discord: Discord-themed colors
Custom CSS Properties
Override theme variables using CSS custom properties:
analytick-widget {
--primary-color: #007bff;
--secondary-color: #6c757d;
--background-color: #ffffff;
--text-color: #212529;
--border-radius: 8px;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}Complete Theme Customization
analytick-widget {
/* Colors */
--primary-color: #ff6b6b;
--primary-hover: #ff5252;
--secondary-color: #4ecdc4;
--background-color: #f8f9fa;
--surface-color: #ffffff;
--text-primary: #2c3e50;
--text-secondary: #7f8c8d;
--border-color: #e9ecef;
/* Typography */
--font-family: 'Inter', sans-serif;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-bold: 600;
/* Spacing */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
/* Layout */
--border-radius: 12px;
--border-radius-sm: 6px;
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2);
/* Animation */
--transition-fast: 0.15s ease;
--transition-normal: 0.3s ease;
--transition-slow: 0.5s ease;
}🌍 Internationalization
Supported Languages
- English (en) - Default
- Spanish (es)
- French (fr)
- German (de)
- Italian (it)
- Portuguese (pt)
- Arabic (ar) - RTL support
- Hebrew (he) - RTL support
- Chinese Simplified (zh-CN)
- Chinese Traditional (zh-TW)
- Japanese (ja)
- Korean (ko)
- Russian (ru)
Language Detection
The widget automatically detects the user's language using:
languageattribute value- Browser language settings
- HTML
langattribute - Falls back to English
RTL Language Support
For right-to-left languages, the widget automatically:
- Flips the layout direction
- Adjusts positioning and animations
- Handles text alignment
- Supports mixed LTR/RTL content
<!-- Automatic RTL detection -->
<analytick-widget language="ar" org-id="..." widget-id="..." base-url="...">
</analytick-widget>
<!-- Force RTL layout -->
<analytick-widget rtl="true" org-id="..." widget-id="..." base-url="...">
</analytick-widget>📱 Mobile & Responsive Design
Responsive Breakpoints
- Mobile: < 768px - Full-screen overlay mode
- Tablet: 768px - 1024px - Adaptive sizing
- Desktop: > 1024px - Fixed positioning
Touch Optimization
- Minimum 44px touch targets
- Swipe gestures for navigation
- Optimized for thumb interaction
- Haptic feedback support (where available)
Performance on Mobile
- Lazy loading of non-critical components
- Optimized animations for 60fps
- Reduced bundle size for mobile networks
- Efficient memory usage
🔧 Development
Project Structure
src/
├── features/ # Feature-based organization
│ ├── widget-manager/ # Main widget controller
│ │ ├── components/ # Widget manager components
│ │ ├── hooks/ # Custom hooks
│ │ ├── types/ # TypeScript definitions
│ │ └── index.tsx # Feature exports
│ └── trigger-button/ # Floating trigger button
│ ├── components/
│ ├── hooks/
│ ├── types/
│ └── index.tsx
├── styles/ # Design tokens and utilities
│ ├── tokens/ # Design system tokens
│ ├── components/ # Component-specific styles
│ └── utilities/ # Utility classes
├── widget/ # Custom element implementation
├── test/ # Test utilities and setup
└── main.ts # Entry pointCode Standards
File Organization
- Maximum 200 lines per file - Break complex components into smaller pieces
- Named exports only - No default exports allowed
- Arrow functions mandatory - Consistent function syntax
- kebab-case file names -
user-profile.tsx,api-client.ts - camelCase component names -
UserProfile,ApiClient
Component Structure Template
// ✅ Correct component structure
// File: src/features/chat/components/message-bubble.tsx
import type { MessageBubbleProps } from '../types/message-bubble-props';
export const MessageBubble = ({ message, timestamp, sender }: MessageBubbleProps) => {
const formatTime = (time: Date) => {
return time.toLocaleTimeString();
};
return (
<div className="message-bubble">
<div className="message-content">{message}</div>
<div className="message-meta">
<span className="sender">{sender}</span>
<span className="timestamp">{formatTime(timestamp)}</span>
</div>
</div>
);
};Type Definitions
// ✅ Separate type files
// File: src/features/chat/types/message-bubble-props.ts
export interface MessageBubbleProps {
message: string;
timestamp: Date;
sender: string;
isOwn?: boolean;
status?: MessageStatus;
}
export type MessageStatus = 'sending' | 'sent' | 'delivered' | 'read' | 'failed';Feature Index Pattern
// ✅ Feature index exports
// File: src/features/chat/index.tsx
export { MessageBubble } from './components/message-bubble';
export { MessageInput } from './components/message-input';
export { ChatContainer } from './components/chat-container';
export { useChat } from './hooks/use-chat';
export { useChatHistory } from './hooks/use-chat-history';
export type { MessageBubbleProps } from './types/message-bubble-props';
export type { ChatState } from './types/chat-state';Available Scripts
| Script | Description |
|--------|-------------|
| npm run dev | Start development server with hot reload |
| npm run dev:test | Start test environment server |
| npm run serve:examples | Serve example files for testing |
| npm run build | Production build with optimization |
| npm run build:dev | Development build without minification |
| npm run build:analyze | Build with bundle analyzer |
| npm test | Run test suite |
| npm run lint | Check code with BiomeJS |
| npm run format | Format code (required before commits) |
| npm run fix | Format and fix linting issues |
| npm run size-check | Check bundle size limits |
Testing Environment
The project includes comprehensive testing environments in the examples/ directory:
Development Hub
Access the testing hub at http://localhost:3001/dev-index.html after running:
npm run dev:testTest Environments
Basic Functionality (
dev-test-basic.html)- Core widget functionality
- API testing utilities
- Error boundary testing
RTL & Internationalization (
dev-test-rtl.html)- Right-to-left language support
- Multi-language testing
- Cultural adaptation
Themes & Customization (
dev-test-themes.html)- Theme switching
- Custom color testing
- Dark mode validation
Multiple Widgets (
dev-test-multiple.html)- State isolation testing
- Performance monitoring
- Memory usage tracking
Mobile & Responsive (
dev-test-mobile.html)- Device simulation
- Touch interaction testing
- Responsive behavior
Production Integration (
script-tag-integration.html)- Real-world integration example
- CDN-like script loading
- Manual initialization
Code Quality Tools
BiomeJS Configuration
- Formatting: Consistent code style with tabs, semicolons, and trailing commas
- Linting: Comprehensive rules for correctness, style, and complexity
- Import Organization: Automatic import sorting and optimization
TypeScript Configuration
- Strict Mode: Full type safety enabled
- Path Mapping: Clean import paths with aliases
- Build Optimization: Separate configs for app and node environments
Performance Guidelines
Bundle Size Targets
- Total Bundle: < 100KB gzipped
- Initial Load: < 50KB gzipped
- Lazy Chunks: < 25KB each
Runtime Performance
- First Paint: < 1s on 3G networks
- Interactive: < 2s on mobile devices
- Memory Usage: < 10MB per widget instance
- Animation: Maintain 60fps on mobile
🚀 Deployment
Build Process
# Clean previous builds
npm run clean
# Run production build
npm run build
# Verify bundle size
npm run size-check
# Test production build
npm run previewBuild Output
The build process generates:
dist/
├── analytick-widget.umd.js # UMD bundle for script tags
├── analytick-widget.es.js # ES modules for bundlers
├── demo.html # Integration demo
└── assets/ # Optimized assetsCDN Deployment
The widget is hosted on Analytick's CDN:
<!-- Production integration -->
<script src="https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js"></script>Version Management
- Latest:
https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js - Specific Version:
https://analytick-widget.analytick.ai/v1.2.3/analytick-widget.umd.js - Development:
https://analytick-widget.analytick.ai/dev/analytick-widget.umd.js
Self-hosting
For self-hosting, serve the files with proper MIME types:
# Nginx configuration
location ~* \.(js|css)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Content-Type "application/javascript" always;
}🔒 Security Considerations
Content Security Policy
Add CSP headers to allow the widget:
<meta http-equiv="Content-Security-Policy"
content="script-src 'self' https://analytick-widget.analytick.ai;
connect-src 'self' wss://your-api.com https://your-api.com;">Data Privacy
- No personal data stored in localStorage
- All communications encrypted via WSS
- GDPR compliant data handling
- Configurable data retention policies
XSS Protection
- Shadow DOM isolation prevents CSS conflicts
- Input sanitization for all user content
- CSP-compliant inline styles only
- No eval() or unsafe dynamic code execution
🐛 Troubleshooting
Common Issues
Widget Not Loading
// Check for JavaScript errors in console
console.log('Widget loaded:', window.AnalytickWidget);
// Verify script tag is correct
<script src="https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js"></script>WebSocket Connection Issues
// Check network connectivity
// Verify base-url is correct and accessible
// Ensure WSS protocol is supportedStyling Conflicts
/* Widget uses Shadow DOM for isolation */
/* If styles aren't applying, check CSS custom properties */
analytick-widget {
--primary-color: #your-color !important;
}Mobile Display Issues
<!-- Ensure viewport meta tag is present -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">Debug Mode
Enable debug logging:
<analytick-widget
debug="true"
org-id="..."
widget-id="..."
base-url="...">
</analytick-widget>Performance Debugging
Monitor performance:
// Check bundle size impact
console.log('Widget bundle size:', performance.getEntriesByName('analytick-widget'));
// Monitor memory usage
console.log('Memory usage:', performance.memory);📚 API Reference
Widget Element API
interface AnalytickWidgetElement extends HTMLElement {
// Properties
orgId: string;
widgetId: string;
baseUrl: string;
theme: string;
language: string;
position: string;
// Methods
open(): void;
close(): void;
toggle(): void;
sendMessage(message: string): void;
setTheme(theme: string): void;
setLanguage(language: string): void;
// Events
addEventListener('widget:ready', handler): void;
addEventListener('widget:open', handler): void;
addEventListener('widget:close', handler): void;
addEventListener('widget:message', handler): void;
addEventListener('widget:error', handler): void;
}JavaScript API
// Access widget instance
const widget = document.querySelector('analytick-widget');
// Open widget programmatically
widget.open();
// Send message
widget.sendMessage('Hello from JavaScript!');
// Listen for events
widget.addEventListener('widget:message', (event) => {
console.log('New message:', event.detail);
});
// Change theme dynamically
widget.setTheme('dark');🤝 Contributing
Development Workflow
Fork and Clone
git clone <your-fork-url> cd intercom-widget npm installCreate Feature Branch
git checkout -b feature/your-feature-nameDevelopment
npm run dev # Start development server npm run dev:test # Start test environmentCode Quality
npm run format # Format code (required) npm run lint # Check linting npm test # Run testsBuild and Test
npm run build # Production build npm run size-check # Verify bundle sizeSubmit PR
- Ensure all tests pass
- Code is formatted with BiomeJS
- Bundle size is within limits
- Include test coverage for new features
Code Review Checklist
- [ ] Follows project code standards
- [ ] Maximum 200 lines per file
- [ ] Named exports only
- [ ] Arrow functions used consistently
- [ ] TypeScript types in separate files
- [ ] BiomeJS formatting applied
- [ ] Tests included for new functionality
- [ ] Bundle size impact acceptable
- [ ] Accessibility requirements met
- [ ] Mobile responsiveness verified
📄 License
MIT License - see LICENSE file for details.
🆘 Support
- Documentation: Check this README and inline code comments
- Issues: Report bugs via GitHub Issues
- Discussions: Use GitHub Discussions for questions
- Examples: Comprehensive examples in
examples/directory
Built with ❤️ using Preact, TypeScript, and modern web standards.
