npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@obvi/feedback-sdk

v1.2.0

Published

Embeddable browser feedback widget — drop into any web app to collect user feedback powered by Obvious

Readme

Obvious Feedback SDK

Embeddable browser widget that lets users submit feedback from any web app. Feedback is routed to Obvious where it is triaged, tracked, and optionally auto-fixed by Autobuild.

Install

npm / yarn / pnpm / bun

npm install @obvi/feedback-sdk

Script tag (CDN)

<script
  src="https://cdn.jsdelivr.net/npm/@obvi/feedback-sdk@latest/dist/index.global.js"
  data-pub-key="fsk_pub_..."
></script>

Or via unpkg:

<script
  src="https://unpkg.com/@obvi/feedback-sdk@latest/dist/index.global.js"
  data-pub-key="fsk_pub_..."
></script>

The script auto-initializes the widget when data-pub-key is present.

Quick start

ES module

import { ObviousFeedback } from "@obvi/feedback-sdk";

const widget = ObviousFeedback.init({
  publicKey: "fsk_pub_...",
});

// Later: widget.destroy()

Script tag with options

<script
  src="https://cdn.jsdelivr.net/npm/@obvi/feedback-sdk@latest/dist/index.global.js"
  data-pub-key="fsk_pub_..."
  data-theme="dark"
  data-env="staging"
></script>

Configuration

Pass options to ObviousFeedback.init() or use data-* attributes on the script tag.

| Option | data-* attribute | Type | Default | Description | | --- | --- | --- | --- | --- | | publicKey | data-pub-key | string | Required | Your workspace feedback key. | | apiBaseUrl | data-api-base-url | string | https://api.app.obvious.ai | Base URL for the Obvious API. | | identityToken | data-identity-token | string | n/a | Signed JWT for verified identity (see below). | | env | data-env | string | production | Environment label attached to submissions. | | prNumber | data-pr-number | number | n/a | PR number for preview environment routing. | | theme | data-theme | 'light' \| 'dark' \| 'system' | light | Widget color scheme. | | triggerLabel | data-trigger-label | string | Open feedback | Tooltip text on the trigger button. | | assistantPosition | n/a | 'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left' | bottom-right | Corner for the floating trigger. | | redactSelectors | n/a | string[] | [] | CSS selectors for elements to redact from DOM snapshots. | | capturePageContext | n/a | boolean | false | Include a redacted DOM snapshot with submissions. | | captureConsole | n/a | boolean | false | Include recent console logs with submissions. | | captureNetwork | n/a | boolean | false | Include recent network requests with submissions. | | sessionReplayUrlResolver | n/a | () => string \| null \| Promise<string \| null> | n/a | Returns a session replay URL (e.g. FullStory, LogRocket). | | visualSuggestions | n/a | { enabled?: boolean } | { enabled: false } | Let reporters preview narrow visual changes before submit. | | previewOnly | n/a | boolean | false | Show the widget in read-only mode without submitting. |

Setup

1. Create a feedback key

In your Obvious workspace, go to Autobuild > Settings and create a Feedback SDK key. You'll get:

  • A public key (fsk_pub_...) — used in the browser SDK.
  • A private key (fsk_secret_...) — used server-side to sign identity tokens. Store it securely; it is only shown once.

Configure allowed domains to restrict which origins can submit feedback with this key.

2. (Optional) Verify user identity

To attach verified user information to feedback submissions, sign an identity token on your server using the private key:

import { SignJWT } from "jose";

const identityToken = await new SignJWT({
  identity: { email: user.email, name: user.name },
})
  .setProtectedHeader({ alg: "HS256", typ: "JWT" })
  .setSubject("fsk_pub_...")
  .setIssuedAt()
  .setExpirationTime("1h")
  .sign(new TextEncoder().encode("fsk_secret_..."));

Pass the resulting token as identityToken in the SDK config. If the token is missing or invalid, feedback is still accepted but marked as unverified.

Theming

The widget uses Shadow DOM and does not inherit host-page styles. Control appearance with:

Theme presets

ObviousFeedback.init({
  publicKey: "fsk_pub_...",
  theme: "dark", // 'light' (default) | 'dark' | 'system'
});
  • light — Always light. Safe for light-only host pages.
  • dark — Always dark.
  • system — Follows the browser prefers-color-scheme media query. Only use when the host page also follows system preference, otherwise the widget may be invisible against the background.

CSS custom properties

Override individual tokens on :root or the widget host element:

:root {
  --obv-feedback-bg: #fafafa;
  --obv-feedback-primary: #0066ff;
  --obv-feedback-text: #1a1a1a;
  --obv-feedback-border: rgba(0, 0, 0, 0.1);
}

Available tokens: --obv-feedback-bg, --obv-feedback-bg-subtle, --obv-feedback-trigger-bg, --obv-feedback-text, --obv-feedback-muted, --obv-feedback-border, --obv-feedback-border-strong, --obv-feedback-primary, --obv-feedback-primary-foreground, --obv-feedback-radius, --obv-feedback-radius-card.

API

ObviousFeedback.init(config): FeedbackSdkHandle

Initialize the widget. Only one instance can be active at a time; calling init again destroys the previous instance.

Returns a handle with:

| Method | Description | | ------------------------------------- | ----------------------------------------------------------------------- | | destroy() | Remove the widget from the page. | | open() | Programmatically open the feedback card. | | getOpenIssueCount() | Number of non-terminal issues submitted in this session. | | subscribeToOpenIssueCount(listener) | Subscribe to open issue count changes. Returns an unsubscribe function. |

Keyboard shortcut

Press Cmd/Ctrl + Shift + . to open the feedback card when the widget is active.

Attachments

Users can attach files (up to 25 MB each, 10 per submission) via drag-and-drop or the file picker in the widget. Attachments are uploaded directly to secure storage via pre-signed URLs.

Visual Suggestions

Visual suggestions are default-off for external consumers. Enable them when you want reporters to select a page element, preview a narrow style change live, and submit that intent with the feedback payload:

ObviousFeedback.init({
  publicKey: "fsk_pub_...",
  visualSuggestions: { enabled: true },
});

Submitted feedback includes context.visualSuggestions with { version: 1, suggestions: [...] }. The SDK only accepts font size, border radius, padding, gap, text color, and background color, and it rejects unsafe CSS syntax before applying or submitting a preview.

Local Dashboard Dogfood

Use a local package link to test SDK changes inside the Obvious dashboard before publishing:

cd /Users/alexolyaiy/Repositories/obvious-feedback-sdk
bun install
bun link
bun run dev

In the dashboard package:

cd /Users/alexolyaiy/Repositories/obvious/dashboard
bun link @obvi/feedback-sdk --no-save

Restart the dashboard so Vite reloads the linked package. Before committing dashboard dependency changes, remove the local link and depend on the published prerelease package.

Status polling

The widget tracks submitted issues and shows their current status (received, in progress, resolved, etc.) in the feedback card. Status is refreshed automatically when the card is opened.

Browser support

The SDK targets ES2020 and uses Shadow DOM, ResizeObserver, and crypto.randomUUID (with fallback). It works in all modern browsers (Chrome, Firefox, Safari, Edge).

Troubleshooting

Widget is invisible

If the widget trigger blends into the page background:

  • Check the theme setting. If your page is light-only, use theme: 'light' (the default), not 'system'.
  • On macOS with auto light/dark mode, theme: 'system' will switch the widget to dark when the OS is in dark mode, even if the host page stays light.

Content Security Policy (CSP)

In browsers that support constructable stylesheets, the widget applies its Shadow DOM CSS with adoptedStyleSheets, which avoids an inline <style> tag. Older browsers fall back to injecting a Shadow DOM <style> tag. If your CSP blocks inline styles in those fallback browsers, add 'unsafe-inline' to style-src for pages that load the widget.

Submissions rejected with 403

The feedback key's allowed domains must include the hostname where the SDK runs. Check your key configuration in Obvious.

License

MIT