Customizable web widget for Analytick platform
npm install @telelogx/analytick-widgetA 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.
- 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+)
If you're using a modern bundler (Webpack, Rollup, Vite, etc.), you can install the widget via NPM:
``bash`
npm install analytick-widget
The easiest way to use the widget in a JavaScript application is via the init function:
`javascript
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
});
`
The widget provides a functional component wrapper for easy integration with React and other JSX frameworks.
`javascript
import { AnalytickWidget } from '@telelogx/analytick-widget';
function MyComponent() {
return (
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:
`html`
widget-id="your-widget-id"
base-url="https://api.yourcompany.com">
`bashClone the repository
git clone
cd intercom-widget
$3
Add the widget to any website with a simple script tag:
`html
Your Website
org-id="your-organization-id"
widget-id="your-widget-id"
base-url="https://your-api-endpoint.com">
`π οΈ Configuration Options
$3
| 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 |$3
| 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 |$3
`html
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">
`π¨ Theming & Customization
$3
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
$3
Override theme variables using CSS custom properties:
`css
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;
}
`$3
`css
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
$3
- 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)
$3
The widget automatically detects the user's language using:
1.
language attribute value
2. Browser language settings
3. HTML lang attribute
4. Falls back to English$3
For right-to-left languages, the widget automatically:
- Flips the layout direction
- Adjusts positioning and animations
- Handles text alignment
- Supports mixed LTR/RTL content
`html
`π± Mobile & Responsive Design
$3
- Mobile: < 768px - Full-screen overlay mode
- Tablet: 768px - 1024px - Adaptive sizing
- Desktop: > 1024px - Fixed positioning
$3
- Minimum 44px touch targets
- Swipe gestures for navigation
- Optimized for thumb interaction
- Haptic feedback support (where available)
$3
- Lazy loading of non-critical components
- Optimized animations for 60fps
- Reduced bundle size for mobile networks
- Efficient memory usage
π§ Development
$3
`
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 point
`$3
#### 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
`typescript
// β
Correct component structure
// File: src/features/chat/components/message-bubble.tsximport type { MessageBubbleProps } from '../types/message-bubble-props';
export const MessageBubble = ({ message, timestamp, sender }: MessageBubbleProps) => {
const formatTime = (time: Date) => {
return time.toLocaleTimeString();
};
return (
{message}
{sender}
{formatTime(timestamp)}
);
};
`#### Type Definitions
`typescript
// β
Separate type files
// File: src/features/chat/types/message-bubble-props.tsexport interface MessageBubbleProps {
message: string;
timestamp: Date;
sender: string;
isOwn?: boolean;
status?: MessageStatus;
}
export type MessageStatus = 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
`#### Feature Index Pattern
`typescript
// β
Feature index exports
// File: src/features/chat/index.tsxexport { 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';
`$3
| 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 |$3
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:`bash
npm run dev:test
`#### Test Environments
1. Basic Functionality (
dev-test-basic.html)
- Core widget functionality
- API testing utilities
- Error boundary testing2. RTL & Internationalization (
dev-test-rtl.html)
- Right-to-left language support
- Multi-language testing
- Cultural adaptation3. Themes & Customization (
dev-test-themes.html)
- Theme switching
- Custom color testing
- Dark mode validation4. Multiple Widgets (
dev-test-multiple.html)
- State isolation testing
- Performance monitoring
- Memory usage tracking5. Mobile & Responsive (
dev-test-mobile.html)
- Device simulation
- Touch interaction testing
- Responsive behavior6. Production Integration (
script-tag-integration.html)
- Real-world integration example
- CDN-like script loading
- Manual initialization$3
#### 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
$3
#### 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
$3
`bash
Clean previous builds
npm run cleanRun production build
npm run buildVerify bundle size
npm run size-checkTest production build
npm run preview
`$3
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 assets
`$3
The widget is hosted on Analytick's CDN:
`html
`$3
- 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$3
For self-hosting, serve the files with proper MIME types:
`nginx
Nginx configuration
location ~* \.(js|css)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Content-Type "application/javascript" always;
}
`π Security Considerations
$3
Add CSP headers to allow the widget:
`html
content="script-src 'self' https://analytick-widget.analytick.ai;
connect-src 'self' wss://your-api.com https://your-api.com;">
`$3
- No personal data stored in localStorage
- All communications encrypted via WSS
- GDPR compliant data handling
- Configurable data retention policies
$3
- 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
$3
#### Widget Not Loading
`javascript
// Check for JavaScript errors in console
console.log('Widget loaded:', window.AnalytickWidget);// Verify script tag is correct
`#### WebSocket Connection Issues
`javascript
// Check network connectivity
// Verify base-url is correct and accessible
// Ensure WSS protocol is supported
`#### Styling Conflicts
`css
/ 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
`html
`$3
Enable debug logging:
`html
debug="true"
org-id="..."
widget-id="..."
base-url="...">
`$3
Monitor performance:
`javascript
// Check bundle size impact
console.log('Widget bundle size:', performance.getEntriesByName('analytick-widget'));// Monitor memory usage
console.log('Memory usage:', performance.memory);
`π API Reference
$3
`typescript
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;
}
`$3
`javascript
// 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
$3
1. Fork and Clone
`bash
git clone
cd intercom-widget
npm install
`2. Create Feature Branch
`bash
git checkout -b feature/your-feature-name
`3. Development
`bash
npm run dev # Start development server
npm run dev:test # Start test environment
`4. Code Quality
`bash
npm run format # Format code (required)
npm run lint # Check linting
npm test # Run tests
`5. Build and Test
`bash
npm run build # Production build
npm run size-check # Verify bundle size
`6. Submit PR
- Ensure all tests pass
- Code is formatted with BiomeJS
- Bundle size is within limits
- Include test coverage for new features
$3
- [ ] 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.