devx-web-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 +166 -0
- package/package.json +28 -0
- package/pnpm-workspace.yaml +2 -0
- package/src/feedback-widget.js +496 -0
- package/src/index.ts +864 -0
- package/tsconfig.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
**DevX Web Feedback Widget**
|
|
2
|
+
|
|
3
|
+
A small, dependency-free feedback widget you can drop into any website. It provides a side tab that opens two feedback flows:
|
|
4
|
+
- "Feedback on this page" — pick an element on the page and include a selector in the feedback
|
|
5
|
+
- "Quick feedback" — general feedback (selector hidden)
|
|
6
|
+
|
|
7
|
+
**Features**
|
|
8
|
+
- **Style-isolated**: runs inside a Shadow DOM to avoid style collisions
|
|
9
|
+
**DevX Web Feedback Widget**
|
|
10
|
+
|
|
11
|
+
A small, dependency-free feedback widget you can drop into any website. It provides a side tab that opens two feedback flows:
|
|
12
|
+
- "Feedback on this page" — pick an element on the page and include a selector in the feedback
|
|
13
|
+
- "Quick feedback" — general feedback (selector hidden)
|
|
14
|
+
|
|
15
|
+
**Features**
|
|
16
|
+
- **Style-isolated**: runs inside a Shadow DOM to avoid style collisions
|
|
17
|
+
- **Two flows**: element picker and quick feedback
|
|
18
|
+
- **Lightweight**: no runtime dependencies for the browser build
|
|
19
|
+
- **Event-driven**: emits a `feedbackwidget:submit` event with the payload
|
|
20
|
+
|
|
21
|
+
**Install (npm / pnpm / yarn)**
|
|
22
|
+
Install the package from the registry (package name from `package.json` is `devx-web-widget`):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# npm
|
|
26
|
+
npm install devx-web-widget
|
|
27
|
+
|
|
28
|
+
# pnpm
|
|
29
|
+
pnpm add devx-web-widget
|
|
30
|
+
|
|
31
|
+
# yarn
|
|
32
|
+
yarn add devx-web-widget
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Quick usage — Browser script (drop-in)**
|
|
36
|
+
Serve `src/feedback-widget.js` or bundle/publish it to a CDN and include it directly on pages where you want feedback capture.
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<script>
|
|
40
|
+
window.FeedbackWidgetConfig = {
|
|
41
|
+
endpoint: 'https://your-api.example.com/feedback', // optional: your ingestion endpoint
|
|
42
|
+
buttonLabel: 'Feedback', // optional
|
|
43
|
+
accentColor: '#2F6FED' // optional
|
|
44
|
+
};
|
|
45
|
+
</script>
|
|
46
|
+
<script src="/path/to/feedback-widget.js"></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Notes:
|
|
50
|
+
- The browser build reads `window.FeedbackWidgetConfig`. If `endpoint` is provided, submissions will be POSTed to it.
|
|
51
|
+
- The browser build exposes a minimal global: `window.FeedbackWidget.open()` and `window.FeedbackWidget.close()`.
|
|
52
|
+
|
|
53
|
+
**Usage — npm package / ES module (DevX projects)**
|
|
54
|
+
Import the shipped module and instantiate the widget in an ESM environment (recommended for DevX apps):
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { FeedbackWidget } from 'devx-web-widget';
|
|
58
|
+
|
|
59
|
+
// Pass an API key and a config object when appropriate
|
|
60
|
+
const widget = new FeedbackWidget(/* apiKeyOrEmpty */ '', {
|
|
61
|
+
buttonLabel: 'Feedback',
|
|
62
|
+
accentColor: '#2F6FED',
|
|
63
|
+
position: 'right' // 'left' | 'right'
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// programmatic control
|
|
67
|
+
widget.open('visible');
|
|
68
|
+
widget.close();
|
|
69
|
+
// widget.destroy();
|
|
70
|
+
|
|
71
|
+
window.addEventListener('feedbackwidget:submit', (e) => {
|
|
72
|
+
console.log('feedback payload', e.detail);
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Important: do not hard-code sensitive API keys into browser bundles. See the "For DevX users" section below for recommended patterns.
|
|
77
|
+
|
|
78
|
+
**Configuration options**
|
|
79
|
+
Pass the config as the second constructor argument (or use `window.FeedbackWidgetConfig` for the browser build):
|
|
80
|
+
|
|
81
|
+
- `buttonLabel` (string) — label shown on the side tab (default: `Feedback`)
|
|
82
|
+
- `backgroundColor` (string) — widget background color (hex)
|
|
83
|
+
- `textColor` (string)
|
|
84
|
+
- `accentColor` (string)
|
|
85
|
+
- `font` (string)
|
|
86
|
+
- `position` (`left` | `right`)
|
|
87
|
+
- `widgetType` (`default` | `chatbot`)
|
|
88
|
+
|
|
89
|
+
**API / endpoint and API Key**
|
|
90
|
+
- Browser build: set `window.FeedbackWidgetConfig.endpoint` to have the widget POST the submitted payload directly to your endpoint.
|
|
91
|
+
- npm/TS class: passing a non-empty API key to `new FeedbackWidget(apiKey, config)` causes the widget to POST a formatted message body to `https://devx.today/v1/widget/ingest` with `Authorization: Bearer <API_KEY>`.
|
|
92
|
+
|
|
93
|
+
Security recommendations (for DevX teams)
|
|
94
|
+
- Do not embed production API keys in client bundles. Instead use a server-side ingestion proxy:
|
|
95
|
+
1. Client widget posts to your internal endpoint (no secret in client)
|
|
96
|
+
2. Your server validates, augments, and forwards to DevX ingestion (`https://devx.today/v1/widget/ingest`) using a server-side-stored API key
|
|
97
|
+
|
|
98
|
+
Example Node/Express forwarder (DevX pattern):
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
// server.js
|
|
102
|
+
import express from 'express';
|
|
103
|
+
import fetch from 'node-fetch';
|
|
104
|
+
|
|
105
|
+
const app = express();
|
|
106
|
+
app.use(express.json());
|
|
107
|
+
|
|
108
|
+
app.post('/api/widget-feedback', async (req, res) => {
|
|
109
|
+
const payload = req.body;
|
|
110
|
+
// perform validation, rate-limiting, enrich payload as needed
|
|
111
|
+
await fetch('https://devx.today/v1/widget/ingest', {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
headers: {
|
|
114
|
+
'Content-Type': 'application/json',
|
|
115
|
+
'Authorization': `Bearer ${process.env.DEVX_API_KEY}`
|
|
116
|
+
},
|
|
117
|
+
body: JSON.stringify(payload)
|
|
118
|
+
});
|
|
119
|
+
res.status(202).end();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
app.listen(3000);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then configure the client/browser widget to use `/api/widget-feedback` as `endpoint`.
|
|
126
|
+
|
|
127
|
+
**Event payload**
|
|
128
|
+
The widget emits `feedbackwidget:submit` with `event.detail` containing:
|
|
129
|
+
|
|
130
|
+
- `optionType`: `page_item_visible` | `page_item_hidden`
|
|
131
|
+
- `elementSelector`: CSS selector string or `null`
|
|
132
|
+
- `pageUrl`, `pageTitle`, `title`, `feedback`, `email`, `submittedAt`
|
|
133
|
+
|
|
134
|
+
**Build & development**
|
|
135
|
+
- Install dependencies (pnpm recommended):
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
pnpm install
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
- Dev (live watch):
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pnpm run dev
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- Build to `dist`:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pnpm run build
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Publishing notes (npm / DevX registry)**
|
|
154
|
+
- Verify `package.json.name` is `devx-web-widget` and update `version`, `license`, and `repository` fields.
|
|
155
|
+
- If publishing to an internal DevX registry, update `.npmrc` with the registry authentication and scope as required.
|
|
156
|
+
|
|
157
|
+
**Contributing / Extending**
|
|
158
|
+
- To add a configurable `endpoint` to the TypeScript constructor I can implement that change and update tests.
|
|
159
|
+
- Consider adding unit tests for selector generation, and an optional E2E demo page for QA.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
If you'd like, I can implement any of the following now:
|
|
164
|
+
- add `endpoint` to the TypeScript constructor (so consumers can pass a custom endpoint from code),
|
|
165
|
+
- produce a UMD build for CDN consumption,
|
|
166
|
+
- create a small demo HTML page that loads the built file and demonstrates submissions.
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "devx-web-widget",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"keywords": [],
|
|
7
|
+
"author": "",
|
|
8
|
+
"license": "ISC",
|
|
9
|
+
"devEngines": {
|
|
10
|
+
"packageManager": {
|
|
11
|
+
"name": "pnpm",
|
|
12
|
+
"version": "^11.1.2",
|
|
13
|
+
"onFail": "download"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^26.1.1",
|
|
19
|
+
"tsx": "^4.23.0",
|
|
20
|
+
"typescript": "^7.0.2",
|
|
21
|
+
"vite": "^8.1.4"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "tsx watch src/index.ts",
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"start": "node dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
}
|