@ihoomanai/chat-widget 2.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 +188 -0
- package/cdn/CDN_DEPLOYMENT.md +199 -0
- package/cdn/SRI_HASHES.md +66 -0
- package/cdn/cloudflare-config.json +203 -0
- package/cdn/cloudfront-config.json +153 -0
- package/cdn/health.json +6 -0
- package/cdn/latest/chat.js +984 -0
- package/cdn/latest/chat.js.map +1 -0
- package/cdn/latest/chat.min.js +2 -0
- package/cdn/latest/chat.min.js.map +1 -0
- package/cdn/manifest.json +42 -0
- package/cdn/nginx.conf +185 -0
- package/cdn/v2/chat.js +984 -0
- package/cdn/v2/chat.js.map +1 -0
- package/cdn/v2/chat.min.js +2 -0
- package/cdn/v2/chat.min.js.map +1 -0
- package/cdn/v2.0.0/chat.js +984 -0
- package/cdn/v2.0.0/chat.js.map +1 -0
- package/cdn/v2.0.0/chat.min.js +2 -0
- package/cdn/v2.0.0/chat.min.js.map +1 -0
- package/dist/index.cjs.js +978 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +972 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.esm.min.js +2 -0
- package/dist/index.esm.min.js.map +1 -0
- package/dist/index.umd.js +984 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/index.umd.min.js +2 -0
- package/dist/index.umd.min.js.map +1 -0
- package/dist/types.d.ts +252 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/widget.d.ts +26 -0
- package/dist/widget.d.ts.map +1 -0
- package/package.json +80 -0
- package/src/index.ts +26 -0
- package/src/types.ts +301 -0
- package/src/widget.ts +1114 -0
package/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# @ihooman/chat-widget
|
|
2
|
+
|
|
3
|
+
Universal chat support widget for any website. Uses secure Widget ID based initialization - no API keys exposed in client code.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ihooman/chat-widget
|
|
9
|
+
# or
|
|
10
|
+
yarn add @ihooman/chat-widget
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @ihooman/chat-widget
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### ES Modules
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { IhoomanChat } from '@ihooman/chat-widget';
|
|
21
|
+
|
|
22
|
+
IhoomanChat.init({
|
|
23
|
+
widgetId: 'wgt_your_widget_id', // Get this from your Ihooman dashboard
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### CommonJS
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const { IhoomanChat } = require('@ihooman/chat-widget');
|
|
31
|
+
|
|
32
|
+
IhoomanChat.init({
|
|
33
|
+
widgetId: 'wgt_your_widget_id',
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### CDN / Script Tag
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<script src="https://cdn.ihooman.ai/widget/latest/chat.min.js"></script>
|
|
41
|
+
<script>
|
|
42
|
+
IhoomanChat.init({
|
|
43
|
+
widgetId: 'wgt_your_widget_id',
|
|
44
|
+
});
|
|
45
|
+
</script>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Configuration Options
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
IhoomanChat.init({
|
|
52
|
+
// Required
|
|
53
|
+
widgetId: 'wgt_your_widget_id',
|
|
54
|
+
|
|
55
|
+
// Optional
|
|
56
|
+
theme: 'light', // 'light' | 'dark'
|
|
57
|
+
position: 'bottom-right', // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
|
|
58
|
+
title: 'Chat Support',
|
|
59
|
+
subtitle: 'We typically reply within minutes',
|
|
60
|
+
welcomeMessage: 'Hi there! 👋 How can we help you today?',
|
|
61
|
+
placeholder: 'Type a message...',
|
|
62
|
+
primaryColor: '#00aeff',
|
|
63
|
+
startOpen: false,
|
|
64
|
+
|
|
65
|
+
// Callbacks
|
|
66
|
+
onReady: () => console.log('Widget ready'),
|
|
67
|
+
onOpen: () => console.log('Widget opened'),
|
|
68
|
+
onClose: () => console.log('Widget closed'),
|
|
69
|
+
onMessage: (message) => console.log('Message:', message),
|
|
70
|
+
onError: (error) => console.error('Error:', error),
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## API Methods
|
|
76
|
+
|
|
77
|
+
### `IhoomanChat.init(config)`
|
|
78
|
+
|
|
79
|
+
Initialize the widget with configuration options. Returns a Promise that resolves when the widget is ready.
|
|
80
|
+
|
|
81
|
+
### `IhoomanChat.open()`
|
|
82
|
+
|
|
83
|
+
Open the chat widget window.
|
|
84
|
+
|
|
85
|
+
### `IhoomanChat.close()`
|
|
86
|
+
|
|
87
|
+
Close the chat widget window.
|
|
88
|
+
|
|
89
|
+
### `IhoomanChat.toggle()`
|
|
90
|
+
|
|
91
|
+
Toggle the chat widget window open/closed.
|
|
92
|
+
|
|
93
|
+
### `IhoomanChat.destroy()`
|
|
94
|
+
|
|
95
|
+
Destroy the widget and clean up all resources.
|
|
96
|
+
|
|
97
|
+
### `IhoomanChat.sendMessage(content)`
|
|
98
|
+
|
|
99
|
+
Send a message programmatically.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
IhoomanChat.sendMessage('Hello, I need help!');
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `IhoomanChat.setUser(user)`
|
|
106
|
+
|
|
107
|
+
Set user information for personalization.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
IhoomanChat.setUser({
|
|
111
|
+
name: 'John Doe',
|
|
112
|
+
email: 'john@example.com',
|
|
113
|
+
metadata: {
|
|
114
|
+
plan: 'premium',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### `IhoomanChat.clearHistory()`
|
|
120
|
+
|
|
121
|
+
Clear chat history and start a new conversation.
|
|
122
|
+
|
|
123
|
+
### `IhoomanChat.on(event, callback)`
|
|
124
|
+
|
|
125
|
+
Subscribe to widget events.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
IhoomanChat.on('message', (message) => {
|
|
129
|
+
console.log('New message:', message);
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### `IhoomanChat.off(event, callback)`
|
|
134
|
+
|
|
135
|
+
Unsubscribe from widget events.
|
|
136
|
+
|
|
137
|
+
### `IhoomanChat.getState()`
|
|
138
|
+
|
|
139
|
+
Get the current widget state.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
const state = IhoomanChat.getState();
|
|
143
|
+
console.log('Is open:', state.isOpen);
|
|
144
|
+
console.log('Messages:', state.messages);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Events
|
|
148
|
+
|
|
149
|
+
- `ready` - Widget is initialized and ready
|
|
150
|
+
- `open` - Widget window opened
|
|
151
|
+
- `close` - Widget window closed
|
|
152
|
+
- `message` - Message sent or received
|
|
153
|
+
- `error` - An error occurred
|
|
154
|
+
|
|
155
|
+
## TypeScript Support
|
|
156
|
+
|
|
157
|
+
This package includes TypeScript type definitions. All types are exported:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import type {
|
|
161
|
+
WidgetConfig,
|
|
162
|
+
WidgetState,
|
|
163
|
+
UserInfo,
|
|
164
|
+
Message,
|
|
165
|
+
WidgetEvent,
|
|
166
|
+
} from '@ihooman/chat-widget';
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Security
|
|
170
|
+
|
|
171
|
+
This widget uses Widget ID based initialization, which means:
|
|
172
|
+
|
|
173
|
+
- ✅ No API keys are exposed in client-side code
|
|
174
|
+
- ✅ Domain validation ensures the widget only works on authorized domains
|
|
175
|
+
- ✅ All sensitive operations happen server-side
|
|
176
|
+
|
|
177
|
+
Get your Widget ID from the [Ihooman Dashboard](https://dashboard.ihooman.ai).
|
|
178
|
+
|
|
179
|
+
## Browser Support
|
|
180
|
+
|
|
181
|
+
- Chrome (latest)
|
|
182
|
+
- Firefox (latest)
|
|
183
|
+
- Safari (latest)
|
|
184
|
+
- Edge (latest)
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT © [Ihooman AI](https://ihooman.ai)
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# CDN Deployment Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to deploy the Ihooman Chat Widget to a CDN with proper URL structure and caching configuration.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The widget is served from `https://cdn.ihooman.ai/widget/` with the following URL structure:
|
|
8
|
+
|
|
9
|
+
| URL Pattern | Description | Cache Duration |
|
|
10
|
+
|-------------|-------------|----------------|
|
|
11
|
+
| `/v2/chat.min.js` | Latest v2.x.x release | 1 year (immutable) |
|
|
12
|
+
| `/v2.1.0/chat.min.js` | Specific version | 1 year (immutable) |
|
|
13
|
+
| `/latest/chat.min.js` | Always latest stable | 5 minutes |
|
|
14
|
+
|
|
15
|
+
## URL Structure
|
|
16
|
+
|
|
17
|
+
### Versioned URLs (Recommended for Production)
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
https://cdn.ihooman.ai/widget/v2/chat.min.js # Latest v2.x.x
|
|
21
|
+
https://cdn.ihooman.ai/widget/v2.1.0/chat.min.js # Specific version
|
|
22
|
+
https://cdn.ihooman.ai/widget/v2.1.0/chat.min.js.map # Source map
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Latest URL (For Development/Testing)
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
https://cdn.ihooman.ai/widget/latest/chat.min.js # Always latest stable
|
|
29
|
+
https://cdn.ihooman.ai/widget/latest/chat.min.js.map # Source map
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Cache Headers
|
|
33
|
+
|
|
34
|
+
### Versioned Content (v2/, v2.1.0/, etc.)
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Cache-Control: public, max-age=31536000, immutable
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- **max-age=31536000**: Cache for 1 year (365 days)
|
|
41
|
+
- **immutable**: Content will never change, browsers can skip revalidation
|
|
42
|
+
- **public**: Can be cached by CDN edge nodes and browsers
|
|
43
|
+
|
|
44
|
+
### Latest Content (/latest/)
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Cache-Control: public, max-age=300
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- **max-age=300**: Cache for 5 minutes
|
|
51
|
+
- **public**: Can be cached by CDN edge nodes and browsers
|
|
52
|
+
- No `immutable` flag since content changes with each release
|
|
53
|
+
|
|
54
|
+
## Deployment Options
|
|
55
|
+
|
|
56
|
+
### Option 1: AWS CloudFront + S3
|
|
57
|
+
|
|
58
|
+
See `cloudfront-config.json` for CloudFront distribution configuration.
|
|
59
|
+
|
|
60
|
+
### Option 2: Cloudflare
|
|
61
|
+
|
|
62
|
+
See `cloudflare-config.json` for Cloudflare configuration.
|
|
63
|
+
|
|
64
|
+
### Option 3: Nginx (Self-Hosted)
|
|
65
|
+
|
|
66
|
+
See `nginx.conf` for Nginx configuration.
|
|
67
|
+
|
|
68
|
+
## Deployment Steps
|
|
69
|
+
|
|
70
|
+
### 1. Build CDN Assets
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cd packages/chat-widget
|
|
74
|
+
npm run build:cdn
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This generates:
|
|
78
|
+
- `cdn/v2/` - Major version directory
|
|
79
|
+
- `cdn/v2.x.x/` - Full version directory
|
|
80
|
+
- `cdn/latest/` - Latest version directory
|
|
81
|
+
- `cdn/manifest.json` - Build manifest with SRI hashes
|
|
82
|
+
|
|
83
|
+
### 2. Upload to CDN Origin
|
|
84
|
+
|
|
85
|
+
Upload the contents of the `cdn/` directory to your CDN origin (S3, R2, or origin server).
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Example: AWS S3
|
|
89
|
+
aws s3 sync cdn/ s3://cdn-ihooman-widget/widget/ \
|
|
90
|
+
--cache-control "public, max-age=31536000, immutable" \
|
|
91
|
+
--exclude "latest/*"
|
|
92
|
+
|
|
93
|
+
aws s3 sync cdn/latest/ s3://cdn-ihooman-widget/widget/latest/ \
|
|
94
|
+
--cache-control "public, max-age=300"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3. Invalidate CDN Cache (if updating)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# AWS CloudFront
|
|
101
|
+
aws cloudfront create-invalidation \
|
|
102
|
+
--distribution-id YOUR_DISTRIBUTION_ID \
|
|
103
|
+
--paths "/widget/latest/*" "/widget/v2/*"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 4. Verify Deployment
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Check versioned URL
|
|
110
|
+
curl -I https://cdn.ihooman.ai/widget/v2.0.0/chat.min.js
|
|
111
|
+
|
|
112
|
+
# Expected headers:
|
|
113
|
+
# Cache-Control: public, max-age=31536000, immutable
|
|
114
|
+
# Content-Type: application/javascript
|
|
115
|
+
|
|
116
|
+
# Check latest URL
|
|
117
|
+
curl -I https://cdn.ihooman.ai/widget/latest/chat.min.js
|
|
118
|
+
|
|
119
|
+
# Expected headers:
|
|
120
|
+
# Cache-Control: public, max-age=300
|
|
121
|
+
# Content-Type: application/javascript
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## CORS Configuration
|
|
125
|
+
|
|
126
|
+
The CDN must allow cross-origin requests for the widget to work on any domain:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
Access-Control-Allow-Origin: *
|
|
130
|
+
Access-Control-Allow-Methods: GET, HEAD, OPTIONS
|
|
131
|
+
Access-Control-Allow-Headers: Content-Type
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Security Headers
|
|
135
|
+
|
|
136
|
+
Recommended security headers for the CDN:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
X-Content-Type-Options: nosniff
|
|
140
|
+
X-Frame-Options: DENY
|
|
141
|
+
Referrer-Policy: strict-origin-when-cross-origin
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Monitoring
|
|
145
|
+
|
|
146
|
+
### Key Metrics to Monitor
|
|
147
|
+
|
|
148
|
+
1. **Cache Hit Ratio**: Should be >95% for versioned URLs
|
|
149
|
+
2. **Latency**: P99 should be <100ms globally
|
|
150
|
+
3. **Error Rate**: Should be <0.1%
|
|
151
|
+
4. **Bandwidth**: Track for cost optimization
|
|
152
|
+
|
|
153
|
+
### Health Check Endpoint
|
|
154
|
+
|
|
155
|
+
Create a health check at `/widget/health.json`:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"status": "healthy",
|
|
160
|
+
"version": "2.0.0",
|
|
161
|
+
"timestamp": "2024-01-01T00:00:00Z"
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Rollback Procedure
|
|
166
|
+
|
|
167
|
+
If a deployment causes issues:
|
|
168
|
+
|
|
169
|
+
1. **For versioned URLs**: Deploy the previous version to the major version directory
|
|
170
|
+
2. **For latest URL**: Update the latest directory to point to the previous stable version
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Rollback latest to v2.0.0
|
|
174
|
+
aws s3 sync s3://cdn-ihooman-widget/widget/v2.0.0/ \
|
|
175
|
+
s3://cdn-ihooman-widget/widget/latest/ \
|
|
176
|
+
--cache-control "public, max-age=300"
|
|
177
|
+
|
|
178
|
+
# Invalidate latest cache
|
|
179
|
+
aws cloudfront create-invalidation \
|
|
180
|
+
--distribution-id YOUR_DISTRIBUTION_ID \
|
|
181
|
+
--paths "/widget/latest/*"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Version Management
|
|
185
|
+
|
|
186
|
+
### Semantic Versioning
|
|
187
|
+
|
|
188
|
+
- **Major version (v2/)**: Updated only for breaking changes
|
|
189
|
+
- **Minor/Patch versions (v2.1.0/)**: Immutable, never updated
|
|
190
|
+
- **Latest**: Always points to the most recent stable release
|
|
191
|
+
|
|
192
|
+
### Release Process
|
|
193
|
+
|
|
194
|
+
1. Build new version: `npm run build:cdn`
|
|
195
|
+
2. Upload new version directory (e.g., `v2.1.1/`)
|
|
196
|
+
3. Update major version directory (`v2/`) with new content
|
|
197
|
+
4. Update `latest/` directory with new content
|
|
198
|
+
5. Invalidate CDN cache for `latest/` and major version
|
|
199
|
+
6. Update `manifest.json` with new SRI hashes
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# SRI Hashes for @ihooman/chat-widget
|
|
2
|
+
|
|
3
|
+
## Version: 2.0.0
|
|
4
|
+
|
|
5
|
+
Build Date: 2026-01-31T15:26:43.871Z
|
|
6
|
+
|
|
7
|
+
## Subresource Integrity (SRI) Hashes
|
|
8
|
+
|
|
9
|
+
Use these hashes to ensure the integrity of the widget script when loading from CDN.
|
|
10
|
+
|
|
11
|
+
### Minified Bundle (Recommended for Production)
|
|
12
|
+
|
|
13
|
+
| Version | URL | SRI Hash |
|
|
14
|
+
|---------|-----|----------|
|
|
15
|
+
| Major (v2) | `https://cdn.ihooman.ai/widget/v2/chat.min.js` | `sha384-mlEtuVKMa+PyLTHKqrCGcvMEKTbkhS4wZbVw89B39K3f7WnGjXkh5N672KmRXPMH` |
|
|
16
|
+
| Full (v2.0.0) | `https://cdn.ihooman.ai/widget/v2.0.0/chat.min.js` | `sha384-mlEtuVKMa+PyLTHKqrCGcvMEKTbkhS4wZbVw89B39K3f7WnGjXkh5N672KmRXPMH` |
|
|
17
|
+
| Latest | `https://cdn.ihooman.ai/widget/latest/chat.min.js` | *(SRI not recommended for latest)* |
|
|
18
|
+
|
|
19
|
+
### Unminified Bundle (For Development/Debugging)
|
|
20
|
+
|
|
21
|
+
| Version | URL | SRI Hash |
|
|
22
|
+
|---------|-----|----------|
|
|
23
|
+
| Major (v2) | `https://cdn.ihooman.ai/widget/v2/chat.js` | `sha384-zCM1t6eGYjrL9CIiDq2M+sJzCcPkXGi8UKO6OMglPGsb/vGj6N2urtUat80fzKGE` |
|
|
24
|
+
| Full (v2.0.0) | `https://cdn.ihooman.ai/widget/v2.0.0/chat.js` | `sha384-zCM1t6eGYjrL9CIiDq2M+sJzCcPkXGi8UKO6OMglPGsb/vGj6N2urtUat80fzKGE` |
|
|
25
|
+
| Latest | `https://cdn.ihooman.ai/widget/latest/chat.js` | *(SRI not recommended for latest)* |
|
|
26
|
+
|
|
27
|
+
## Usage Examples
|
|
28
|
+
|
|
29
|
+
### With SRI (Recommended for versioned URLs)
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<script src="https://cdn.ihooman.ai/widget/v2.0.0/chat.min.js"
|
|
33
|
+
integrity="sha384-mlEtuVKMa+PyLTHKqrCGcvMEKTbkhS4wZbVw89B39K3f7WnGjXkh5N672KmRXPMH"
|
|
34
|
+
crossorigin="anonymous"></script>
|
|
35
|
+
<script>
|
|
36
|
+
IhoomanChat.init({
|
|
37
|
+
widgetId: 'YOUR_WIDGET_ID'
|
|
38
|
+
});
|
|
39
|
+
</script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Without SRI (For latest URL)
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<script src="https://cdn.ihooman.ai/widget/latest/chat.min.js"></script>
|
|
46
|
+
<script>
|
|
47
|
+
IhoomanChat.init({
|
|
48
|
+
widgetId: 'YOUR_WIDGET_ID'
|
|
49
|
+
});
|
|
50
|
+
</script>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Notes
|
|
54
|
+
|
|
55
|
+
- **SRI hashes are recommended** for versioned URLs to ensure script integrity
|
|
56
|
+
- **SRI is not recommended** for the `latest` URL as the content changes with each release
|
|
57
|
+
- The `crossorigin="anonymous"` attribute is required when using SRI
|
|
58
|
+
- Major version URLs (e.g., `/v2/`) always point to the latest patch within that major version
|
|
59
|
+
- Full version URLs (e.g., `/v2.1.0/`) are immutable and will never change
|
|
60
|
+
|
|
61
|
+
## Cache Headers
|
|
62
|
+
|
|
63
|
+
| URL Type | Cache-Control |
|
|
64
|
+
|----------|---------------|
|
|
65
|
+
| Versioned (`/v2/`, `/v2.1.0/`) | `public, max-age=31536000, immutable` |
|
|
66
|
+
| Latest (`/latest/`) | `public, max-age=300` |
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developers.cloudflare.com/api/",
|
|
3
|
+
"_comment": "Cloudflare Configuration for Ihooman Chat Widget CDN",
|
|
4
|
+
"zone": {
|
|
5
|
+
"name": "ihooman.ai",
|
|
6
|
+
"settings": {
|
|
7
|
+
"ssl": "full_strict",
|
|
8
|
+
"min_tls_version": "1.2",
|
|
9
|
+
"http3": "on",
|
|
10
|
+
"brotli": "on",
|
|
11
|
+
"minify": {
|
|
12
|
+
"js": false,
|
|
13
|
+
"css": false,
|
|
14
|
+
"html": false
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"dns_records": [
|
|
19
|
+
{
|
|
20
|
+
"type": "CNAME",
|
|
21
|
+
"name": "cdn",
|
|
22
|
+
"content": "cdn-ihooman-widget.r2.cloudflarestorage.com",
|
|
23
|
+
"proxied": true,
|
|
24
|
+
"comment": "CDN subdomain for widget distribution"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"page_rules": [
|
|
28
|
+
{
|
|
29
|
+
"_comment": "Versioned URLs - Long cache with immutable",
|
|
30
|
+
"targets": [
|
|
31
|
+
{
|
|
32
|
+
"target": "url",
|
|
33
|
+
"constraint": {
|
|
34
|
+
"operator": "matches",
|
|
35
|
+
"value": "cdn.ihooman.ai/widget/v*"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"actions": [
|
|
40
|
+
{
|
|
41
|
+
"id": "cache_level",
|
|
42
|
+
"value": "cache_everything"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "edge_cache_ttl",
|
|
46
|
+
"value": 31536000
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "browser_cache_ttl",
|
|
50
|
+
"value": 31536000
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"priority": 1,
|
|
54
|
+
"status": "active"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"_comment": "Latest URL - Short cache",
|
|
58
|
+
"targets": [
|
|
59
|
+
{
|
|
60
|
+
"target": "url",
|
|
61
|
+
"constraint": {
|
|
62
|
+
"operator": "matches",
|
|
63
|
+
"value": "cdn.ihooman.ai/widget/latest/*"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"actions": [
|
|
68
|
+
{
|
|
69
|
+
"id": "cache_level",
|
|
70
|
+
"value": "cache_everything"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "edge_cache_ttl",
|
|
74
|
+
"value": 300
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "browser_cache_ttl",
|
|
78
|
+
"value": 300
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"priority": 2,
|
|
82
|
+
"status": "active"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"cache_rules": [
|
|
86
|
+
{
|
|
87
|
+
"name": "Widget Versioned Cache",
|
|
88
|
+
"description": "Cache versioned widget files for 1 year",
|
|
89
|
+
"expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/v\"))",
|
|
90
|
+
"action": "set_cache_settings",
|
|
91
|
+
"action_parameters": {
|
|
92
|
+
"cache": true,
|
|
93
|
+
"edge_ttl": {
|
|
94
|
+
"mode": "override_origin",
|
|
95
|
+
"default": 31536000
|
|
96
|
+
},
|
|
97
|
+
"browser_ttl": {
|
|
98
|
+
"mode": "override_origin",
|
|
99
|
+
"default": 31536000
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "Widget Latest Cache",
|
|
105
|
+
"description": "Cache latest widget files for 5 minutes",
|
|
106
|
+
"expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/latest/\"))",
|
|
107
|
+
"action": "set_cache_settings",
|
|
108
|
+
"action_parameters": {
|
|
109
|
+
"cache": true,
|
|
110
|
+
"edge_ttl": {
|
|
111
|
+
"mode": "override_origin",
|
|
112
|
+
"default": 300
|
|
113
|
+
},
|
|
114
|
+
"browser_ttl": {
|
|
115
|
+
"mode": "override_origin",
|
|
116
|
+
"default": 300
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"transform_rules": {
|
|
122
|
+
"response_headers": [
|
|
123
|
+
{
|
|
124
|
+
"name": "Widget CORS Headers",
|
|
125
|
+
"description": "Add CORS headers for widget requests",
|
|
126
|
+
"expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/\"))",
|
|
127
|
+
"action": "set",
|
|
128
|
+
"action_parameters": {
|
|
129
|
+
"headers": [
|
|
130
|
+
{
|
|
131
|
+
"name": "Access-Control-Allow-Origin",
|
|
132
|
+
"value": "*"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "Access-Control-Allow-Methods",
|
|
136
|
+
"value": "GET, HEAD, OPTIONS"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"name": "Access-Control-Allow-Headers",
|
|
140
|
+
"value": "Content-Type, Accept, Origin"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "Access-Control-Max-Age",
|
|
144
|
+
"value": "86400"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"name": "X-Content-Type-Options",
|
|
148
|
+
"value": "nosniff"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"name": "X-Frame-Options",
|
|
152
|
+
"value": "DENY"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"name": "Referrer-Policy",
|
|
156
|
+
"value": "strict-origin-when-cross-origin"
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"name": "Widget Versioned Cache Headers",
|
|
163
|
+
"description": "Add immutable cache header for versioned files",
|
|
164
|
+
"expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/v\") and not starts_with(http.request.uri.path, \"/widget/latest/\"))",
|
|
165
|
+
"action": "set",
|
|
166
|
+
"action_parameters": {
|
|
167
|
+
"headers": [
|
|
168
|
+
{
|
|
169
|
+
"name": "Cache-Control",
|
|
170
|
+
"value": "public, max-age=31536000, immutable"
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "Widget Latest Cache Headers",
|
|
177
|
+
"description": "Add short cache header for latest files",
|
|
178
|
+
"expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/latest/\"))",
|
|
179
|
+
"action": "set",
|
|
180
|
+
"action_parameters": {
|
|
181
|
+
"headers": [
|
|
182
|
+
{
|
|
183
|
+
"name": "Cache-Control",
|
|
184
|
+
"value": "public, max-age=300"
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"r2_bucket": {
|
|
192
|
+
"name": "cdn-ihooman-widget",
|
|
193
|
+
"location": "auto",
|
|
194
|
+
"cors_rules": [
|
|
195
|
+
{
|
|
196
|
+
"allowed_origins": ["*"],
|
|
197
|
+
"allowed_methods": ["GET", "HEAD"],
|
|
198
|
+
"allowed_headers": ["*"],
|
|
199
|
+
"max_age_seconds": 86400
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
}
|