chatnest 3.4.1 → 3.4.3

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.
@@ -12,7 +12,7 @@ A lightweight, customizable AI chat widget. Drop it into any website in minutes.
12
12
 
13
13
  **CDN**
14
14
  ```html
15
- <script src="https://cdn.jsdelivr.net/npm/chatnest@3.4.1/dist/chatnest.min.js"></script>
15
+ <script src="https://cdn.jsdelivr.net/npm/chatnest@3.4.3/dist/chatnest.min.js"></script>
16
16
  ```
17
17
 
18
18
  **npm**
@@ -28,7 +28,7 @@ import Chatnest from 'chatnest';
28
28
  ## Quick Start
29
29
 
30
30
  ```html
31
- <script src="https://cdn.jsdelivr.net/npm/chatnest@3.4.1/dist/chatnest.min.js"></script>
31
+ <script src="https://cdn.jsdelivr.net/npm/chatnest@3.4.3/dist/chatnest.min.js"></script>
32
32
  <script>
33
33
  document.addEventListener('DOMContentLoaded', () => {
34
34
  new Chatnest({
@@ -74,6 +74,7 @@ import Chatnest from 'chatnest';
74
74
  | `apiResponseFormat` | `object` | `{ response, products, productItem }` | Map response field names from your API |
75
75
  | `apiDataFormat` | `string` | `'json'` | `'json'` or `'form-data'` |
76
76
  | `useMultipartFormData` | `boolean` | `true` | Use multipart encoding for file uploads |
77
+ | `userId` | `string\|function\|null` | `null` | Override the `user_id` sent on every API call. Pass a static string, a function `(userManager) => string`, or `null` to use the auto-generated ID. If `nativeForm.useEmailAsUserId` is `true` the submitted email takes over automatically after form submission. |
77
78
  | `transformResponse` | `function` | `null` | Transform the raw API response before display |
78
79
  | `productInjectionMarker` | `string\|array` | see below | Text marker(s) after which the product carousel is inserted |
79
80
 
@@ -127,6 +128,8 @@ import Chatnest from 'chatnest';
127
128
  | `chatBackgroundColor` | `string` | `'#ffffff'` | Chat panel background color |
128
129
  | `chatBackgroundImage` | `string` | `null` | CSS background-image for the chat panel |
129
130
  | `sendButtonIconSize` | `number` | `24` | Send button icon size in px |
131
+ | `showPrivacyNotice` | `boolean` | `false` | Show a small privacy notice below the input |
132
+ | `privacyNoticeText` | `string` | `'Messages may be stored to improve responses.'` | Privacy notice copy |
130
133
 
131
134
  ### Toggle Button
132
135
 
@@ -152,6 +155,40 @@ The small speech-bubble pop-up that appears above the toggle button before the c
152
155
  | `textBoxTextColor` | `string` | `'primary'` | `'primary'` (uses `primaryColor`), `'default'`, or any hex |
153
156
  | `textBoxSpacingFromToggle` | `number` | `0` | Gap between the pop-up and toggle button in px |
154
157
 
158
+ ### Native Lead Form
159
+
160
+ A fully built-in, no-dependency lead-capture form. Fields, labels, and validation are all customisable. Data is saved to `localStorage` and, optionally, the submitted email is used as the API `user_id` from that point on.
161
+
162
+ | Option | Type | Default | Description |
163
+ |--------|------|---------|-------------|
164
+ | `nativeForm.enabled` | `boolean` | `false` | Enable the native form |
165
+ | `nativeForm.trigger` | `string` | `'onOpen'` | When to show — `'onOpen'` (chat opens) or `'onFirstMessage'` (first send attempt) |
166
+ | `nativeForm.title` | `string` | `'Before we start'` | Modal heading |
167
+ | `nativeForm.subtitle` | `string` | `'Tell us a little about yourself.'` | Modal sub-heading |
168
+ | `nativeForm.submitLabel` | `string` | `'Start chatting'` | Submit button label |
169
+ | `nativeForm.useEmailAsUserId` | `boolean` | `true` | After submission, set the email field value as the persistent API `user_id` |
170
+ | `nativeForm.storageKey` | `string\|null` | `null` | localStorage key prefix. `null` → auto (`cnf_<hostname>`) |
171
+ | `nativeForm.fields` | `array` | name + email + phone | Array of field descriptors — see table below |
172
+ | `nativeForm.onSubmit` | `async function\|null` | `null` | Optional async callback `(formData) => void\|false`. Return `false` to block submission. |
173
+
174
+ **Field descriptor shape**
175
+
176
+ | Key | Type | Required | Description |
177
+ |-----|------|----------|-------------|
178
+ | `name` | `string` | yes | Field key, also used as the `localStorage` data property |
179
+ | `label` | `string` | yes | Label shown above the input |
180
+ | `type` | `string` | no | HTML input type — `'text'` `'email'` `'tel'` `'number'` etc. Default `'text'` |
181
+ | `required` | `boolean` | no | Mark field as required. Default `false` |
182
+ | `placeholder` | `string` | no | Input placeholder text |
183
+ | `validate` | `function` | no | Custom validator `(value: string) => errorMessage \| ''`. Overrides built-in type checks. |
184
+
185
+ **localStorage keys written on submit**
186
+
187
+ | Key | Value |
188
+ |-----|-------|
189
+ | `cnf_<hostname>_submitted` | `"true"` |
190
+ | `cnf_<hostname>_data` | JSON — all field values + `submittedAt` ISO timestamp |
191
+
155
192
  ### HubSpot Lead Form
156
193
 
157
194
  Displays a lead-capture form before or during chat. Requires HubSpot portal credentials.
@@ -163,7 +200,7 @@ Displays a lead-capture form before or during chat. Requires HubSpot portal cred
163
200
  | `hubspot.formGuid` | `string` | `''` | HubSpot form GUID |
164
201
  | `hubspot.triggerKeywords` | `array` | `['pricing','demo','contact','quote','help','support']` | Keywords that trigger the form |
165
202
  | `showFormOnStart` | `boolean` | `true` | Show form when chat opens for new users |
166
- | `useEmailAsUserId` | `boolean` | `true` | Use submitted email as the persistent user ID |
203
+ | `useEmailAsUserId` | `boolean` | `true` | Use submitted email as the persistent user ID (HubSpot form only) |
167
204
  | `formTitle` | `string` | `'Give Your Details'` | Form modal title |
168
205
  | `formSubtitle` | `string` | `'Please provide your information to start chatting.'` | Form modal subtitle |
169
206
 
@@ -197,6 +234,108 @@ Persist chat history in Supabase so sessions survive across devices and browsers
197
234
 
198
235
  ---
199
236
 
237
+ ## Native Lead Form
238
+
239
+ Capture user details before or during chat — no HubSpot account needed. All data stays in the user's browser.
240
+
241
+ ### Minimal setup
242
+
243
+ ```js
244
+ new Chatnest({
245
+ apiEndpoint: 'https://your-api.com/chat',
246
+ nativeForm: {
247
+ enabled: true
248
+ }
249
+ });
250
+ ```
251
+
252
+ Shows a name + email + phone form when the chat opens. After submission the email becomes the persistent `user_id` on every API request.
253
+
254
+ ### Custom fields
255
+
256
+ ```js
257
+ new Chatnest({
258
+ apiEndpoint: 'https://your-api.com/chat',
259
+ nativeForm: {
260
+ enabled: true,
261
+ trigger: 'onFirstMessage', // intercept first send attempt
262
+ title: 'Quick intro',
263
+ subtitle: 'We use this to personalise your experience.',
264
+ submitLabel: 'Let\'s go',
265
+ fields: [
266
+ { name: 'fullname', label: 'Your name', type: 'text', required: true },
267
+ { name: 'email', label: 'Work email', type: 'email', required: true },
268
+ { name: 'company', label: 'Company', type: 'text', required: false,
269
+ validate: (v) => v.length >= 2 ? '' : 'Enter your company name.' }
270
+ ]
271
+ }
272
+ });
273
+ ```
274
+
275
+ ### Custom submit hook
276
+
277
+ ```js
278
+ new Chatnest({
279
+ nativeForm: {
280
+ enabled: true,
281
+ onSubmit: async (formData) => {
282
+ // formData = { fullname, email, company, submittedAt }
283
+ const res = await fetch('/api/leads', {
284
+ method: 'POST',
285
+ headers: { 'Content-Type': 'application/json' },
286
+ body: JSON.stringify(formData)
287
+ });
288
+ if (!res.ok) return false; // returning false shows an error and keeps the form open
289
+ }
290
+ }
291
+ });
292
+ ```
293
+
294
+ ### Reading stored data in your own code
295
+
296
+ ```js
297
+ // Check if the user already submitted
298
+ const submitted = localStorage.getItem('cnf_yourdomain.com_submitted') === 'true';
299
+
300
+ // Read field values
301
+ const data = JSON.parse(localStorage.getItem('cnf_yourdomain.com_data') || 'null');
302
+ // { fullname: 'Jane Doe', email: 'jane@co.com', submittedAt: '2025-04-03T...' }
303
+ ```
304
+
305
+ ---
306
+
307
+ ## User ID Control
308
+
309
+ By default ChatNest auto-generates a random `user_id` per browser and persists it in `localStorage`. You can override this at any level of precision:
310
+
311
+ ```js
312
+ // 1. Static — same ID for every visitor (useful for authenticated apps)
313
+ new Chatnest({ userId: 'user_42' });
314
+
315
+ // 2. Dynamic — evaluated on every API request
316
+ new Chatnest({
317
+ userId: (userManager) => {
318
+ // userManager.currentUser is the auto-generated or email-derived ID
319
+ return window.__myApp?.loggedInUserId || userManager.currentUser;
320
+ }
321
+ });
322
+
323
+ // 3. Email from nativeForm — no extra config needed
324
+ // When nativeForm.useEmailAsUserId is true (the default),
325
+ // the email the user submits automatically becomes userManager.currentUser
326
+ // and is used on all subsequent requests.
327
+ new Chatnest({
328
+ nativeForm: { enabled: true, useEmailAsUserId: true }
329
+ });
330
+ ```
331
+
332
+ **Resolution order on each API call:**
333
+ 1. `config.userId` (string or function), if set
334
+ 2. `userManager.currentUser` — which is the submitted email after `nativeForm` or `hubspot` form submission (when `useEmailAsUserId: true`)
335
+ 3. Auto-generated `user_<domain><timestamp>_<random>` persisted in `localStorage`
336
+
337
+ ---
338
+
200
339
  ## Supabase Setup
201
340
 
202
341
  ### 1. Create the table