@pixelmatters/markup 1.32.5 → 1.34.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixelmatters/markup",
3
- "version": "1.32.5",
3
+ "version": "1.34.0",
4
4
  "description": "Embeddable feedback widget for collecting visual bug reports, screenshots, and comments on live web apps.",
5
5
  "keywords": [
6
6
  "annotation",
@@ -65,7 +65,6 @@
65
65
  "@types/react-dom": "^19.3.0",
66
66
  "convex": "^1.38.0",
67
67
  "es-module-lexer": "^2.3.2",
68
- "html-to-image": "1.11.13",
69
68
  "preact": "^10.29.8",
70
69
  "radix-ui": "^1.6.7",
71
70
  "react": "^19.3.0",
@@ -7,7 +7,7 @@ sources:
7
7
  - 'Pixelmatters/markup:packages/widget/src/widget.ts'
8
8
  metadata:
9
9
  library: pixelmatters-markup
10
- library_version: '1.32.5'
10
+ library_version: '1.34.0'
11
11
  ---
12
12
 
13
13
  `@pixelmatters/markup` is a Preact widget that runs inside a shadow DOM and talks to a hosted Convex backend at `https://<deployment>.convex.site`. The host page calls `init({ apiUrl, apiKey })` once at the app root and gets back a `destroy()` function. Everything else lives inside the widget bundle: pin anchoring, threads, mentions, identity, screenshots, real-time updates.
@@ -26,7 +26,7 @@ For a `<script>`-tag drop-in (no bundler / CMS / page-builder), use the inline E
26
26
 
27
27
  ```html
28
28
  <script type="module">
29
- import { init } from 'https://esm.sh/@pixelmatters/markup@1.32.5'
29
+ import { init } from 'https://esm.sh/@pixelmatters/markup@1.34.0'
30
30
  init({ apiUrl: '…', apiKey: '…' })
31
31
  </script>
32
32
  ```
@@ -36,7 +36,7 @@ If the host disallows inline JS, use the auto-init form. `data-markup-widget="tr
36
36
  ```html
37
37
  <script
38
38
  type="module"
39
- src="https://esm.sh/@pixelmatters/markup@1.32.5"
39
+ src="https://esm.sh/@pixelmatters/markup@1.34.0"
40
40
  data-markup-widget="true"
41
41
  data-api-url="…"
42
42
  data-api-key="…"
@@ -148,7 +148,7 @@ Auto-masked by default (regardless of `strictScrub`):
148
148
 
149
149
  HTML attributes the widget honours on the host page:
150
150
 
151
- - `data-markup-private` and `data-markup-redact` are always masked, on top of auto-detection, even inside a `data-markup-safe` wrapper. The element and everything inside it (text, images, icons, child elements) become one solid black block, so it can go on a whole container. On a `<canvas>`, `<video>` or `<iframe>` it also blacks out any image beside it in the same parent.
151
+ - `data-markup-private` and `data-markup-redact` are always masked, on top of auto-detection, even inside a `data-markup-safe` wrapper. The element and everything inside it (text, images, icons, child elements) become one solid black block, so it can go on a whole container.
152
152
  - `data-markup-safe` **exempts** the descendants of the element carrying it from auto-detection and from `redactSelector` / `strictScrub`. The element itself is not exempt, so put it on a wrapper, not on the field. Use it sparingly: it un-protects every field inside except those marked `data-markup-private` / `data-markup-redact`.
153
153
  - `data-markup-skip` removes the element from the screenshot entirely, rather than masking it.
154
154
  - All of the above reaches into open shadow roots (web components), nested ones included. A `data-markup-safe` on a component's host exempts its shadow fields. `redactSelector` is matched inside each shadow root separately, so a descendant selector can't cross a shadow boundary. A closed shadow root's own content is never captured; light-DOM children slotted into it are, and are masked as usual.
@@ -195,7 +195,7 @@ Walk these in order when the widget is misbehaving:
195
195
  | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
196
196
  | Toolbar doesn't appear, console warns `[markup] init() requires both apiUrl and apiKey` | One of the env vars is unset / undefined at the call site | Confirm the framework's env-var prefix (`VITE_…`, `NEXT_PUBLIC_…`, etc.) and that `.env` is being loaded |
197
197
  | Toolbar doesn't appear, console shows `403 Origin not allowed` | Host is not in `allowedDomains` | Dashboard → Settings → Domains, add the exact host (`app.example.com`) or a wildcard (`*.example.com` matches any subdomain depth) |
198
- | Toolbar renders unstyled, or threads never load | CSP is missing `style-src 'unsafe-inline'` (the stylesheet is a `<style>` element in the shadow root) or the deployment origins under `connect-src` | See the CSP bullet under **Don'ts** |
198
+ | Toolbar renders unstyled, or threads never load | CSP is missing `style-src 'unsafe-inline'` on Safari before 16.4 or Firefox before 101 (where the stylesheet falls back to a `<style>` element in the shadow root) or the deployment origins under `connect-src` | See the CSP bullet under **Don'ts** |
199
199
  | Comments show initials where profile pictures are expected | The host's CSP `img-src` blocks the picture host, or the account has none set | Add the picture host to `img-src`. Initials are the intended fallback, not a bug |
200
200
  | `@` types a literal character, no picker | The member fetch failed (a `403`/`429` on `/widget/members` degrades silently by design) | Check the network tab for `/widget/members`; the usual cause is the domain allowlist |
201
201
  | `401 Invalid api key` | Key revoked, wrong project, or copy-paste truncation | Mint a fresh key and replace the env var |
@@ -208,7 +208,7 @@ Walk these in order when the widget is misbehaving:
208
208
  | Popup sign-in flashes and closes | Popup origin failed `allowedDomains` check, or the stored JWT was expired and dropped | Add the host to the project's allowlist; the popup re-validates. Expired JWTs are dropped on the next load, so sign in again |
209
209
  | HMR leaves duplicate toolbars in dev | Hot reload re-runs `init` without cleanup | Use `useMarkup` on React, or return the `destroy` from `onMounted` / `onMount` so HMR can call it. (The history wrapper itself is module-scoped, so repeated init/destroy cycles no longer leak listeners.) |
210
210
  | Screenshot is missing my custom field | Auto-mask matched the input (e.g. `autocomplete="cc-number"`) or your selector | Expand the composer's "N fields redacted" chip to see which selectors were masked; add `data-markup-safe` on a wrapper (not the field itself) to exempt it from auto-detection |
211
- | Widget invisible behind host UI | Z-index conflict on the shadow host element | The widget mounts `<div id="markup-widget">` at `document.body`; raise its `z-index` from host CSS if you must |
211
+ | Widget invisible behind host UI | Something on the page stacks above the host element, which already sits at the top `z-index`: an element with the same `z-index` later in the DOM, or the top layer (a modal `<dialog>`, a popover) | A plain `z-index` rule on the host has no effect, by design. Lower the other element's, or set `--markup-z-index` on `#markup-widget` or `:root` |
212
212
 
213
213
  ## Don'ts
214
214
 
@@ -216,8 +216,8 @@ Walk these in order when the widget is misbehaving:
216
216
  - **Don't wrap in a provider component.** `init` is the whole public API.
217
217
  - **Don't call `init` inside a route component.** Mount at the app root once.
218
218
  - **Don't hardcode the API key.** Use env vars so rotations don't require a code change.
219
- - **Don't ship CDN URLs without a version pin.** `@pixelmatters/markup@1.32.5`, not `@pixelmatters/markup`.
220
- - **Don't add `https://*.convex.site` to `connect-src` and assume that's the whole CSP story.** The deployment domain (`<your-deployment>.convex.site`) is what the widget hits over HTTP, and it must be listed explicitly. Live thread updates go to `wss://<your-deployment>.convex.cloud`, an origin the widget derives from `apiUrl`, so `connect-src` needs both. `img-src` needs `blob:`, `data:`, and the host serving profile pictures; `style-src` needs `'unsafe-inline'` because the widget appends its stylesheet as a `<style>` element inside its shadow root. Add `https://esm.sh` to `script-src` only if you took the CDN path.
219
+ - **Don't ship CDN URLs without a version pin.** `@pixelmatters/markup@1.34.0`, not `@pixelmatters/markup`.
220
+ - **Don't add `https://*.convex.site` to `connect-src` and assume that's the whole CSP story.** The deployment domain (`<your-deployment>.convex.site`) is what the widget hits over HTTP, and it must be listed explicitly. Live thread updates go to `wss://<your-deployment>.convex.cloud`, an origin the widget derives from `apiUrl`, so `connect-src` needs both. `img-src` needs `blob:`, `data:`, and the host serving profile pictures; `style-src` needs `'unsafe-inline'` only for Safari before 16.4 and Firefox before 101, where the widget falls back to a `<style>` element inside its shadow root; everywhere else it adopts a constructed stylesheet, which CSP doesn't block. Add `https://esm.sh` to `script-src` only if you took the CDN path.
221
221
 
222
222
  ## Versioning & releases
223
223