@telelogx/analytick-widget 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +727 -0
- package/dist/analytick-widget.css +1 -0
- package/dist/analytick-widget.es.js +8326 -0
- package/dist/analytick-widget.umd.js +1 -0
- package/dist/demo.html +123 -0
- package/dist/vite.svg +1 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,727 @@
|
|
|
1
|
+
# Analytick Widget
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- **Lightweight & Fast**: Built with Preact for minimal bundle size (~100KB gzipped)
|
|
8
|
+
- **Easy Integration**: Simple script tag embedding with custom element API
|
|
9
|
+
- **Real-time Messaging**: WebSocket support with STOMP protocol
|
|
10
|
+
- **Internationalization**: Multi-language support with RTL layout capabilities
|
|
11
|
+
- **Customizable Theming**: CSS custom properties with multiple preset themes
|
|
12
|
+
- **Mobile Responsive**: Touch-friendly design with responsive layouts
|
|
13
|
+
- **TypeScript**: Full type safety and excellent developer experience
|
|
14
|
+
- **Shadow DOM**: Style isolation prevents CSS conflicts
|
|
15
|
+
- **Accessibility**: WCAG compliant with screen reader support
|
|
16
|
+
- **Cross-browser**: Supports all modern browsers (Chrome 60+, Firefox 63+, Safari 10.1+, Edge 79+)
|
|
17
|
+
|
|
18
|
+
## 📦 NPM Package Usage
|
|
19
|
+
|
|
20
|
+
If you're using a modern bundler (Webpack, Rollup, Vite, etc.), you can install the widget via NPM:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install analytick-widget
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Programmatic Initialization
|
|
27
|
+
|
|
28
|
+
The easiest way to use the widget in a JavaScript application is via the `init` function:
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
import { init } from 'analytick-widget';
|
|
32
|
+
|
|
33
|
+
// Initialize and automatically inject the widget into document.body
|
|
34
|
+
init({
|
|
35
|
+
orgId: 'your-organization-id',
|
|
36
|
+
widgetId: 'your-widget-id',
|
|
37
|
+
baseUrl: 'https://api.yourcompany.com',
|
|
38
|
+
primaryColor: '#3C5BFF' // Optional
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Framework Integration (React, Vue, etc.)
|
|
43
|
+
|
|
44
|
+
Since the widget is built as a Standard Web Component (Custom Element), it works seamlessly with all major frameworks.
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
import { AnalytickWidget } from 'analytick-widget';
|
|
48
|
+
|
|
49
|
+
// The custom element <analytick-widget> is automatically registered on import.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
In your JSX/HTML:
|
|
53
|
+
```html
|
|
54
|
+
<analytick-widget
|
|
55
|
+
org-id="your-org-id"
|
|
56
|
+
widget-id="your-widget-id"
|
|
57
|
+
base-url="https://api.yourcompany.com">
|
|
58
|
+
</analytick-widget>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 📦 Quick Start
|
|
62
|
+
|
|
63
|
+
### Installation & Development
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Clone the repository
|
|
67
|
+
git clone <repository-url>
|
|
68
|
+
cd intercom-widget
|
|
69
|
+
|
|
70
|
+
# Install dependencies
|
|
71
|
+
npm install
|
|
72
|
+
|
|
73
|
+
# Start development server
|
|
74
|
+
npm run dev
|
|
75
|
+
|
|
76
|
+
# Build for production
|
|
77
|
+
npm run build
|
|
78
|
+
|
|
79
|
+
# Run tests
|
|
80
|
+
npm test
|
|
81
|
+
|
|
82
|
+
# Format code (required before commits)
|
|
83
|
+
npm run format
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Basic Integration
|
|
87
|
+
|
|
88
|
+
Add the widget to any website with a simple script tag:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<!DOCTYPE html>
|
|
92
|
+
<html>
|
|
93
|
+
<head>
|
|
94
|
+
<title>Your Website</title>
|
|
95
|
+
</head>
|
|
96
|
+
<body>
|
|
97
|
+
<!-- Your website content -->
|
|
98
|
+
|
|
99
|
+
<!-- Widget container -->
|
|
100
|
+
<analytick-widget
|
|
101
|
+
org-id="your-organization-id"
|
|
102
|
+
widget-id="your-widget-id"
|
|
103
|
+
base-url="https://your-api-endpoint.com">
|
|
104
|
+
</analytick-widget>
|
|
105
|
+
|
|
106
|
+
<!-- Widget script -->
|
|
107
|
+
<script src="https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js"></script>
|
|
108
|
+
</body>
|
|
109
|
+
</html>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 🛠️ Configuration Options
|
|
113
|
+
|
|
114
|
+
### Required Attributes
|
|
115
|
+
|
|
116
|
+
| Attribute | Type | Description |
|
|
117
|
+
|-----------|------|-------------|
|
|
118
|
+
| `org-id` | string | Your organization identifier |
|
|
119
|
+
| `widget-id` | string | Unique widget instance identifier |
|
|
120
|
+
| `base-url` | string | API endpoint URL for WebSocket connections |
|
|
121
|
+
|
|
122
|
+
### Optional Attributes
|
|
123
|
+
|
|
124
|
+
| Attribute | Type | Default | Description |
|
|
125
|
+
|-----------|------|---------|-------------|
|
|
126
|
+
| `theme` | string | `"default"` | Theme preset (`default`, `dark`, `intercom`, `slack`, `discord`) |
|
|
127
|
+
| `language` | string | `"auto"` | Language code (`en`, `es`, `fr`, `ar`, `he`, etc.) |
|
|
128
|
+
| `position` | string | `"bottom-right"` | Widget position (`bottom-right`, `bottom-left`, `top-right`, `top-left`) |
|
|
129
|
+
| `auto-open` | boolean | `false` | Automatically open widget on page load |
|
|
130
|
+
| `greeting-message` | string | - | Custom greeting message |
|
|
131
|
+
| `primary-color` | string | - | Custom primary color (hex code) |
|
|
132
|
+
| `rtl` | boolean | `false` | Force right-to-left layout |
|
|
133
|
+
|
|
134
|
+
### Advanced Configuration Example
|
|
135
|
+
|
|
136
|
+
```html
|
|
137
|
+
<analytick-widget
|
|
138
|
+
org-id="org_123456789"
|
|
139
|
+
widget-id="widget_abcdef"
|
|
140
|
+
base-url="https://api.yourcompany.com"
|
|
141
|
+
theme="dark"
|
|
142
|
+
language="es"
|
|
143
|
+
position="bottom-left"
|
|
144
|
+
auto-open="true"
|
|
145
|
+
greeting-message="¡Hola! ¿Cómo podemos ayudarte?"
|
|
146
|
+
primary-color="#007bff"
|
|
147
|
+
rtl="false">
|
|
148
|
+
</analytick-widget>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## 🎨 Theming & Customization
|
|
152
|
+
|
|
153
|
+
### Built-in Themes
|
|
154
|
+
|
|
155
|
+
The widget includes several preset themes:
|
|
156
|
+
|
|
157
|
+
- **default**: Clean, modern design with blue accents
|
|
158
|
+
- **dark**: Dark mode with high contrast
|
|
159
|
+
- **intercom**: Intercom-inspired styling
|
|
160
|
+
- **slack**: Slack-like appearance
|
|
161
|
+
- **discord**: Discord-themed colors
|
|
162
|
+
|
|
163
|
+
### Custom CSS Properties
|
|
164
|
+
|
|
165
|
+
Override theme variables using CSS custom properties:
|
|
166
|
+
|
|
167
|
+
```css
|
|
168
|
+
analytick-widget {
|
|
169
|
+
--primary-color: #007bff;
|
|
170
|
+
--secondary-color: #6c757d;
|
|
171
|
+
--background-color: #ffffff;
|
|
172
|
+
--text-color: #212529;
|
|
173
|
+
--border-radius: 8px;
|
|
174
|
+
--shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
175
|
+
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Complete Theme Customization
|
|
180
|
+
|
|
181
|
+
```css
|
|
182
|
+
analytick-widget {
|
|
183
|
+
/* Colors */
|
|
184
|
+
--primary-color: #ff6b6b;
|
|
185
|
+
--primary-hover: #ff5252;
|
|
186
|
+
--secondary-color: #4ecdc4;
|
|
187
|
+
--background-color: #f8f9fa;
|
|
188
|
+
--surface-color: #ffffff;
|
|
189
|
+
--text-primary: #2c3e50;
|
|
190
|
+
--text-secondary: #7f8c8d;
|
|
191
|
+
--border-color: #e9ecef;
|
|
192
|
+
|
|
193
|
+
/* Typography */
|
|
194
|
+
--font-family: 'Inter', sans-serif;
|
|
195
|
+
--font-size-sm: 0.875rem;
|
|
196
|
+
--font-size-base: 1rem;
|
|
197
|
+
--font-size-lg: 1.125rem;
|
|
198
|
+
--font-weight-normal: 400;
|
|
199
|
+
--font-weight-medium: 500;
|
|
200
|
+
--font-weight-bold: 600;
|
|
201
|
+
|
|
202
|
+
/* Spacing */
|
|
203
|
+
--spacing-xs: 0.25rem;
|
|
204
|
+
--spacing-sm: 0.5rem;
|
|
205
|
+
--spacing-md: 1rem;
|
|
206
|
+
--spacing-lg: 1.5rem;
|
|
207
|
+
--spacing-xl: 2rem;
|
|
208
|
+
|
|
209
|
+
/* Layout */
|
|
210
|
+
--border-radius: 12px;
|
|
211
|
+
--border-radius-sm: 6px;
|
|
212
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
213
|
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
214
|
+
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2);
|
|
215
|
+
|
|
216
|
+
/* Animation */
|
|
217
|
+
--transition-fast: 0.15s ease;
|
|
218
|
+
--transition-normal: 0.3s ease;
|
|
219
|
+
--transition-slow: 0.5s ease;
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## 🌍 Internationalization
|
|
224
|
+
|
|
225
|
+
### Supported Languages
|
|
226
|
+
|
|
227
|
+
- English (en) - Default
|
|
228
|
+
- Spanish (es)
|
|
229
|
+
- French (fr)
|
|
230
|
+
- German (de)
|
|
231
|
+
- Italian (it)
|
|
232
|
+
- Portuguese (pt)
|
|
233
|
+
- Arabic (ar) - RTL support
|
|
234
|
+
- Hebrew (he) - RTL support
|
|
235
|
+
- Chinese Simplified (zh-CN)
|
|
236
|
+
- Chinese Traditional (zh-TW)
|
|
237
|
+
- Japanese (ja)
|
|
238
|
+
- Korean (ko)
|
|
239
|
+
- Russian (ru)
|
|
240
|
+
|
|
241
|
+
### Language Detection
|
|
242
|
+
|
|
243
|
+
The widget automatically detects the user's language using:
|
|
244
|
+
1. `language` attribute value
|
|
245
|
+
2. Browser language settings
|
|
246
|
+
3. HTML `lang` attribute
|
|
247
|
+
4. Falls back to English
|
|
248
|
+
|
|
249
|
+
### RTL Language Support
|
|
250
|
+
|
|
251
|
+
For right-to-left languages, the widget automatically:
|
|
252
|
+
- Flips the layout direction
|
|
253
|
+
- Adjusts positioning and animations
|
|
254
|
+
- Handles text alignment
|
|
255
|
+
- Supports mixed LTR/RTL content
|
|
256
|
+
|
|
257
|
+
```html
|
|
258
|
+
<!-- Automatic RTL detection -->
|
|
259
|
+
<analytick-widget language="ar" org-id="..." widget-id="..." base-url="...">
|
|
260
|
+
</analytick-widget>
|
|
261
|
+
|
|
262
|
+
<!-- Force RTL layout -->
|
|
263
|
+
<analytick-widget rtl="true" org-id="..." widget-id="..." base-url="...">
|
|
264
|
+
</analytick-widget>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## 📱 Mobile & Responsive Design
|
|
268
|
+
|
|
269
|
+
### Responsive Breakpoints
|
|
270
|
+
|
|
271
|
+
- **Mobile**: < 768px - Full-screen overlay mode
|
|
272
|
+
- **Tablet**: 768px - 1024px - Adaptive sizing
|
|
273
|
+
- **Desktop**: > 1024px - Fixed positioning
|
|
274
|
+
|
|
275
|
+
### Touch Optimization
|
|
276
|
+
|
|
277
|
+
- Minimum 44px touch targets
|
|
278
|
+
- Swipe gestures for navigation
|
|
279
|
+
- Optimized for thumb interaction
|
|
280
|
+
- Haptic feedback support (where available)
|
|
281
|
+
|
|
282
|
+
### Performance on Mobile
|
|
283
|
+
|
|
284
|
+
- Lazy loading of non-critical components
|
|
285
|
+
- Optimized animations for 60fps
|
|
286
|
+
- Reduced bundle size for mobile networks
|
|
287
|
+
- Efficient memory usage
|
|
288
|
+
|
|
289
|
+
## 🔧 Development
|
|
290
|
+
|
|
291
|
+
### Project Structure
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
src/
|
|
295
|
+
├── features/ # Feature-based organization
|
|
296
|
+
│ ├── widget-manager/ # Main widget controller
|
|
297
|
+
│ │ ├── components/ # Widget manager components
|
|
298
|
+
│ │ ├── hooks/ # Custom hooks
|
|
299
|
+
│ │ ├── types/ # TypeScript definitions
|
|
300
|
+
│ │ └── index.tsx # Feature exports
|
|
301
|
+
│ └── trigger-button/ # Floating trigger button
|
|
302
|
+
│ ├── components/
|
|
303
|
+
│ ├── hooks/
|
|
304
|
+
│ ├── types/
|
|
305
|
+
│ └── index.tsx
|
|
306
|
+
├── styles/ # Design tokens and utilities
|
|
307
|
+
│ ├── tokens/ # Design system tokens
|
|
308
|
+
│ ├── components/ # Component-specific styles
|
|
309
|
+
│ └── utilities/ # Utility classes
|
|
310
|
+
├── widget/ # Custom element implementation
|
|
311
|
+
├── test/ # Test utilities and setup
|
|
312
|
+
└── main.ts # Entry point
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Code Standards
|
|
316
|
+
|
|
317
|
+
#### File Organization
|
|
318
|
+
- **Maximum 200 lines per file** - Break complex components into smaller pieces
|
|
319
|
+
- **Named exports only** - No default exports allowed
|
|
320
|
+
- **Arrow functions mandatory** - Consistent function syntax
|
|
321
|
+
- **kebab-case file names** - `user-profile.tsx`, `api-client.ts`
|
|
322
|
+
- **camelCase component names** - `UserProfile`, `ApiClient`
|
|
323
|
+
|
|
324
|
+
#### Component Structure Template
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// ✅ Correct component structure
|
|
328
|
+
// File: src/features/chat/components/message-bubble.tsx
|
|
329
|
+
|
|
330
|
+
import type { MessageBubbleProps } from '../types/message-bubble-props';
|
|
331
|
+
|
|
332
|
+
export const MessageBubble = ({ message, timestamp, sender }: MessageBubbleProps) => {
|
|
333
|
+
const formatTime = (time: Date) => {
|
|
334
|
+
return time.toLocaleTimeString();
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
return (
|
|
338
|
+
<div className="message-bubble">
|
|
339
|
+
<div className="message-content">{message}</div>
|
|
340
|
+
<div className="message-meta">
|
|
341
|
+
<span className="sender">{sender}</span>
|
|
342
|
+
<span className="timestamp">{formatTime(timestamp)}</span>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
);
|
|
346
|
+
};
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### Type Definitions
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
// ✅ Separate type files
|
|
353
|
+
// File: src/features/chat/types/message-bubble-props.ts
|
|
354
|
+
|
|
355
|
+
export interface MessageBubbleProps {
|
|
356
|
+
message: string;
|
|
357
|
+
timestamp: Date;
|
|
358
|
+
sender: string;
|
|
359
|
+
isOwn?: boolean;
|
|
360
|
+
status?: MessageStatus;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export type MessageStatus = 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### Feature Index Pattern
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
// ✅ Feature index exports
|
|
370
|
+
// File: src/features/chat/index.tsx
|
|
371
|
+
|
|
372
|
+
export { MessageBubble } from './components/message-bubble';
|
|
373
|
+
export { MessageInput } from './components/message-input';
|
|
374
|
+
export { ChatContainer } from './components/chat-container';
|
|
375
|
+
export { useChat } from './hooks/use-chat';
|
|
376
|
+
export { useChatHistory } from './hooks/use-chat-history';
|
|
377
|
+
export type { MessageBubbleProps } from './types/message-bubble-props';
|
|
378
|
+
export type { ChatState } from './types/chat-state';
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Available Scripts
|
|
382
|
+
|
|
383
|
+
| Script | Description |
|
|
384
|
+
|--------|-------------|
|
|
385
|
+
| `npm run dev` | Start development server with hot reload |
|
|
386
|
+
| `npm run dev:test` | Start test environment server |
|
|
387
|
+
| `npm run serve:examples` | Serve example files for testing |
|
|
388
|
+
| `npm run build` | Production build with optimization |
|
|
389
|
+
| `npm run build:dev` | Development build without minification |
|
|
390
|
+
| `npm run build:analyze` | Build with bundle analyzer |
|
|
391
|
+
| `npm test` | Run test suite |
|
|
392
|
+
| `npm run lint` | Check code with BiomeJS |
|
|
393
|
+
| `npm run format` | Format code (required before commits) |
|
|
394
|
+
| `npm run fix` | Format and fix linting issues |
|
|
395
|
+
| `npm run size-check` | Check bundle size limits |
|
|
396
|
+
|
|
397
|
+
### Testing Environment
|
|
398
|
+
|
|
399
|
+
The project includes comprehensive testing environments in the `examples/` directory:
|
|
400
|
+
|
|
401
|
+
#### Development Hub
|
|
402
|
+
Access the testing hub at `http://localhost:3001/dev-index.html` after running:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
npm run dev:test
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
#### Test Environments
|
|
409
|
+
|
|
410
|
+
1. **Basic Functionality** (`dev-test-basic.html`)
|
|
411
|
+
- Core widget functionality
|
|
412
|
+
- API testing utilities
|
|
413
|
+
- Error boundary testing
|
|
414
|
+
|
|
415
|
+
2. **RTL & Internationalization** (`dev-test-rtl.html`)
|
|
416
|
+
- Right-to-left language support
|
|
417
|
+
- Multi-language testing
|
|
418
|
+
- Cultural adaptation
|
|
419
|
+
|
|
420
|
+
3. **Themes & Customization** (`dev-test-themes.html`)
|
|
421
|
+
- Theme switching
|
|
422
|
+
- Custom color testing
|
|
423
|
+
- Dark mode validation
|
|
424
|
+
|
|
425
|
+
4. **Multiple Widgets** (`dev-test-multiple.html`)
|
|
426
|
+
- State isolation testing
|
|
427
|
+
- Performance monitoring
|
|
428
|
+
- Memory usage tracking
|
|
429
|
+
|
|
430
|
+
5. **Mobile & Responsive** (`dev-test-mobile.html`)
|
|
431
|
+
- Device simulation
|
|
432
|
+
- Touch interaction testing
|
|
433
|
+
- Responsive behavior
|
|
434
|
+
|
|
435
|
+
6. **Production Integration** (`script-tag-integration.html`)
|
|
436
|
+
- Real-world integration example
|
|
437
|
+
- CDN-like script loading
|
|
438
|
+
- Manual initialization
|
|
439
|
+
|
|
440
|
+
### Code Quality Tools
|
|
441
|
+
|
|
442
|
+
#### BiomeJS Configuration
|
|
443
|
+
- **Formatting**: Consistent code style with tabs, semicolons, and trailing commas
|
|
444
|
+
- **Linting**: Comprehensive rules for correctness, style, and complexity
|
|
445
|
+
- **Import Organization**: Automatic import sorting and optimization
|
|
446
|
+
|
|
447
|
+
#### TypeScript Configuration
|
|
448
|
+
- **Strict Mode**: Full type safety enabled
|
|
449
|
+
- **Path Mapping**: Clean import paths with aliases
|
|
450
|
+
- **Build Optimization**: Separate configs for app and node environments
|
|
451
|
+
|
|
452
|
+
### Performance Guidelines
|
|
453
|
+
|
|
454
|
+
#### Bundle Size Targets
|
|
455
|
+
- **Total Bundle**: < 100KB gzipped
|
|
456
|
+
- **Initial Load**: < 50KB gzipped
|
|
457
|
+
- **Lazy Chunks**: < 25KB each
|
|
458
|
+
|
|
459
|
+
#### Runtime Performance
|
|
460
|
+
- **First Paint**: < 1s on 3G networks
|
|
461
|
+
- **Interactive**: < 2s on mobile devices
|
|
462
|
+
- **Memory Usage**: < 10MB per widget instance
|
|
463
|
+
- **Animation**: Maintain 60fps on mobile
|
|
464
|
+
|
|
465
|
+
## 🚀 Deployment
|
|
466
|
+
|
|
467
|
+
### Build Process
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
# Clean previous builds
|
|
471
|
+
npm run clean
|
|
472
|
+
|
|
473
|
+
# Run production build
|
|
474
|
+
npm run build
|
|
475
|
+
|
|
476
|
+
# Verify bundle size
|
|
477
|
+
npm run size-check
|
|
478
|
+
|
|
479
|
+
# Test production build
|
|
480
|
+
npm run preview
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Build Output
|
|
484
|
+
|
|
485
|
+
The build process generates:
|
|
486
|
+
|
|
487
|
+
```
|
|
488
|
+
dist/
|
|
489
|
+
├── analytick-widget.umd.js # UMD bundle for script tags
|
|
490
|
+
├── analytick-widget.es.js # ES modules for bundlers
|
|
491
|
+
├── demo.html # Integration demo
|
|
492
|
+
└── assets/ # Optimized assets
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### CDN Deployment
|
|
496
|
+
|
|
497
|
+
The widget is hosted on Analytick's CDN:
|
|
498
|
+
|
|
499
|
+
```html
|
|
500
|
+
<!-- Production integration -->
|
|
501
|
+
<script src="https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js"></script>
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Version Management
|
|
505
|
+
|
|
506
|
+
- **Latest**: `https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js`
|
|
507
|
+
- **Specific Version**: `https://analytick-widget.analytick.ai/v1.2.3/analytick-widget.umd.js`
|
|
508
|
+
- **Development**: `https://analytick-widget.analytick.ai/dev/analytick-widget.umd.js`
|
|
509
|
+
|
|
510
|
+
### Self-hosting
|
|
511
|
+
|
|
512
|
+
For self-hosting, serve the files with proper MIME types:
|
|
513
|
+
|
|
514
|
+
```nginx
|
|
515
|
+
# Nginx configuration
|
|
516
|
+
location ~* \.(js|css)$ {
|
|
517
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
518
|
+
add_header Content-Type "application/javascript" always;
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
## 🔒 Security Considerations
|
|
523
|
+
|
|
524
|
+
### Content Security Policy
|
|
525
|
+
|
|
526
|
+
Add CSP headers to allow the widget:
|
|
527
|
+
|
|
528
|
+
```html
|
|
529
|
+
<meta http-equiv="Content-Security-Policy"
|
|
530
|
+
content="script-src 'self' https://analytick-widget.analytick.ai;
|
|
531
|
+
connect-src 'self' wss://your-api.com https://your-api.com;">
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Data Privacy
|
|
535
|
+
|
|
536
|
+
- No personal data stored in localStorage
|
|
537
|
+
- All communications encrypted via WSS
|
|
538
|
+
- GDPR compliant data handling
|
|
539
|
+
- Configurable data retention policies
|
|
540
|
+
|
|
541
|
+
### XSS Protection
|
|
542
|
+
|
|
543
|
+
- Shadow DOM isolation prevents CSS conflicts
|
|
544
|
+
- Input sanitization for all user content
|
|
545
|
+
- CSP-compliant inline styles only
|
|
546
|
+
- No eval() or unsafe dynamic code execution
|
|
547
|
+
|
|
548
|
+
## 🐛 Troubleshooting
|
|
549
|
+
|
|
550
|
+
### Common Issues
|
|
551
|
+
|
|
552
|
+
#### Widget Not Loading
|
|
553
|
+
```javascript
|
|
554
|
+
// Check for JavaScript errors in console
|
|
555
|
+
console.log('Widget loaded:', window.AnalytickWidget);
|
|
556
|
+
|
|
557
|
+
// Verify script tag is correct
|
|
558
|
+
<script src="https://analytick-widget.analytick.ai/latest/analytick-widget.umd.js"></script>
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
#### WebSocket Connection Issues
|
|
562
|
+
```javascript
|
|
563
|
+
// Check network connectivity
|
|
564
|
+
// Verify base-url is correct and accessible
|
|
565
|
+
// Ensure WSS protocol is supported
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
#### Styling Conflicts
|
|
569
|
+
```css
|
|
570
|
+
/* Widget uses Shadow DOM for isolation */
|
|
571
|
+
/* If styles aren't applying, check CSS custom properties */
|
|
572
|
+
analytick-widget {
|
|
573
|
+
--primary-color: #your-color !important;
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
#### Mobile Display Issues
|
|
578
|
+
```html
|
|
579
|
+
<!-- Ensure viewport meta tag is present -->
|
|
580
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### Debug Mode
|
|
584
|
+
|
|
585
|
+
Enable debug logging:
|
|
586
|
+
|
|
587
|
+
```html
|
|
588
|
+
<analytick-widget
|
|
589
|
+
debug="true"
|
|
590
|
+
org-id="..."
|
|
591
|
+
widget-id="..."
|
|
592
|
+
base-url="...">
|
|
593
|
+
</analytick-widget>
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Performance Debugging
|
|
597
|
+
|
|
598
|
+
Monitor performance:
|
|
599
|
+
|
|
600
|
+
```javascript
|
|
601
|
+
// Check bundle size impact
|
|
602
|
+
console.log('Widget bundle size:', performance.getEntriesByName('analytick-widget'));
|
|
603
|
+
|
|
604
|
+
// Monitor memory usage
|
|
605
|
+
console.log('Memory usage:', performance.memory);
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
## 📚 API Reference
|
|
609
|
+
|
|
610
|
+
### Widget Element API
|
|
611
|
+
|
|
612
|
+
```typescript
|
|
613
|
+
interface AnalytickWidgetElement extends HTMLElement {
|
|
614
|
+
// Properties
|
|
615
|
+
orgId: string;
|
|
616
|
+
widgetId: string;
|
|
617
|
+
baseUrl: string;
|
|
618
|
+
theme: string;
|
|
619
|
+
language: string;
|
|
620
|
+
position: string;
|
|
621
|
+
|
|
622
|
+
// Methods
|
|
623
|
+
open(): void;
|
|
624
|
+
close(): void;
|
|
625
|
+
toggle(): void;
|
|
626
|
+
sendMessage(message: string): void;
|
|
627
|
+
setTheme(theme: string): void;
|
|
628
|
+
setLanguage(language: string): void;
|
|
629
|
+
|
|
630
|
+
// Events
|
|
631
|
+
addEventListener('widget:ready', handler): void;
|
|
632
|
+
addEventListener('widget:open', handler): void;
|
|
633
|
+
addEventListener('widget:close', handler): void;
|
|
634
|
+
addEventListener('widget:message', handler): void;
|
|
635
|
+
addEventListener('widget:error', handler): void;
|
|
636
|
+
}
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### JavaScript API
|
|
640
|
+
|
|
641
|
+
```javascript
|
|
642
|
+
// Access widget instance
|
|
643
|
+
const widget = document.querySelector('analytick-widget');
|
|
644
|
+
|
|
645
|
+
// Open widget programmatically
|
|
646
|
+
widget.open();
|
|
647
|
+
|
|
648
|
+
// Send message
|
|
649
|
+
widget.sendMessage('Hello from JavaScript!');
|
|
650
|
+
|
|
651
|
+
// Listen for events
|
|
652
|
+
widget.addEventListener('widget:message', (event) => {
|
|
653
|
+
console.log('New message:', event.detail);
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
// Change theme dynamically
|
|
657
|
+
widget.setTheme('dark');
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
## 🤝 Contributing
|
|
661
|
+
|
|
662
|
+
### Development Workflow
|
|
663
|
+
|
|
664
|
+
1. **Fork and Clone**
|
|
665
|
+
```bash
|
|
666
|
+
git clone <your-fork-url>
|
|
667
|
+
cd intercom-widget
|
|
668
|
+
npm install
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
2. **Create Feature Branch**
|
|
672
|
+
```bash
|
|
673
|
+
git checkout -b feature/your-feature-name
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
3. **Development**
|
|
677
|
+
```bash
|
|
678
|
+
npm run dev # Start development server
|
|
679
|
+
npm run dev:test # Start test environment
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
4. **Code Quality**
|
|
683
|
+
```bash
|
|
684
|
+
npm run format # Format code (required)
|
|
685
|
+
npm run lint # Check linting
|
|
686
|
+
npm test # Run tests
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
5. **Build and Test**
|
|
690
|
+
```bash
|
|
691
|
+
npm run build # Production build
|
|
692
|
+
npm run size-check # Verify bundle size
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
6. **Submit PR**
|
|
696
|
+
- Ensure all tests pass
|
|
697
|
+
- Code is formatted with BiomeJS
|
|
698
|
+
- Bundle size is within limits
|
|
699
|
+
- Include test coverage for new features
|
|
700
|
+
|
|
701
|
+
### Code Review Checklist
|
|
702
|
+
|
|
703
|
+
- [ ] Follows project code standards
|
|
704
|
+
- [ ] Maximum 200 lines per file
|
|
705
|
+
- [ ] Named exports only
|
|
706
|
+
- [ ] Arrow functions used consistently
|
|
707
|
+
- [ ] TypeScript types in separate files
|
|
708
|
+
- [ ] BiomeJS formatting applied
|
|
709
|
+
- [ ] Tests included for new functionality
|
|
710
|
+
- [ ] Bundle size impact acceptable
|
|
711
|
+
- [ ] Accessibility requirements met
|
|
712
|
+
- [ ] Mobile responsiveness verified
|
|
713
|
+
|
|
714
|
+
## 📄 License
|
|
715
|
+
|
|
716
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
717
|
+
|
|
718
|
+
## 🆘 Support
|
|
719
|
+
|
|
720
|
+
- **Documentation**: Check this README and inline code comments
|
|
721
|
+
- **Issues**: Report bugs via GitHub Issues
|
|
722
|
+
- **Discussions**: Use GitHub Discussions for questions
|
|
723
|
+
- **Examples**: Comprehensive examples in `examples/` directory
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
Built with ❤️ using Preact, TypeScript, and modern web standards.
|