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

@foreloop/feedback

v0.14.0

Published

Foreloop feedback widget and typed client: send annotated product feedback straight into your Foreloop loops.

Readme

@foreloop/feedback

The Foreloop feedback widget and typed client. People send feedback, bugs, and ideas from inside your product — optionally annotated ("Show us where") and screenshotted — straight into your Foreloop organization's loops.

Install

Two paths. They install the same widget and accept the same options, differing only in how the asset loads and how configuration is passed.

Script tag — no build step. The package ships the built browser asset at dist/foreloop-feedback.js, so a plain site can skip npm entirely:

<script
  src="https://cdn.jsdelivr.net/npm/@foreloop/feedback@latest/dist/foreloop-feedback.js"
  data-api-key="slpk_..."
  async
></script>

npm — when your app has a bundler and knows who is signed in:

npm install @foreloop/feedback

The API key must be a write-only signal:write key — it can submit feedback and nothing else, which is why it may live in browser code. Generate one from your Foreloop organization's Widget page.

Full step-by-step directions for both paths, including CSP requirements and a troubleshooting table, are in Install and use the Foreloop feedback widget.

JavaScript initializer

Use the initializer when your app knows who is signed in:

import { initForeloopFeedback } from "@foreloop/feedback";

await initForeloopFeedback({
  apiKey: "slpk_...",
  reporterName: signedInUser?.email,
  project: "subject_…", // optional Foreloop project target
});

project optionally scopes new submissions to a Foreloop project; omitting it preserves default routing. reporterName pre-populates the widget's Email field — the host resolves the signed-in user; the widget never infers identity from browser state.

Headless (your own form UI):

import { sendForeloopFeedback } from "@foreloop/feedback";

await sendForeloopFeedback({
  apiKey: "slpk_...",
  comment: "The save action did not confirm completion.",
  severity: "high",
  url: window.location.href,
});

sendForeloopFeedback accepts an injected fetchImpl for servers, edge runtimes, and tests.

Options reference

Every option can be passed to initForeloopFeedback({...}) or, for the plain <script> embed, as a data-* attribute (camelCase → kebab-case: buttonColorDarkdata-button-color-dark). All are optional except the API key.

| Option | Type / values | Default | What it does | | --- | --- | --- | --- | | apiKey (data-api-key, alias foreloopKey) | slpk_... string | — | Write-only signal:write key. Required. | | project | subject_... string | — | Scopes new signals to a Foreloop project; omit for default routing. | | trigger | CSS selector | — | Changes the whole presentation. Clicks on matching host elements open the widget (delegated document-level capture listener, so SPA re-renders keep working). The floating launcher disappears and the panel renders as a centered 420px modal over a dimmed backdrop (aria-modal, focus trapped, focus returned to the trigger on close). Without it, the widget is a floating bottom-right launcher with an anchored panel. | | buttonColor | CSS color or "transparent" | icon defaults (#171717/#fff) | Themes the launcher chip in both tones. Contrasting ink is derived from the color's luminance automatically. "transparent" removes the chip so the glyph floats on the page, with ink following the page tone. | | buttonColorLight, buttonColorDark | CSS color | buttonColor | Per-tone overrides. buttonColorDark shows over light pages, buttonColorLight over dark pages (named after the icon variants). | | buttonLabel (data-label also works) | string | "Foreloop Feedback" | The launcher's aria-label. No visible text — the launcher is icon-only. | | placeholder | string | none | Placeholder for the message textarea. By default the textarea is empty. | | productArea | string | — | Recorded in the signal's Widget context. | | reporterName | string | — | Pre-fills the Email field. The widget never infers identity itself. | | severity | "low".."critical" | unset | Pre-selects the Priority field (shown only for the bug category). | | sensitivity | Foreloop sensitivity | "customer_pii" | Sensitivity stamped on the signal. | | includeQuery | boolean | false | Include the page URL's query/fragment in the payload (stripped by default). | | includeUrlEvidence | boolean | true | Attach the page URL as an evidence ref when no screenshot is attached. | | captureScreenshot | boolean | true | Show the "Select capture area" section (browser consent flow; nothing captures silently). | | styleNonce (data-style-nonce) | string | — | CSP nonce applied to the injected stylesheet for strict style-src hosts. | | scriptUrl | URL | CDN default | Initializer-only: where to load the widget asset from. | | data-auto-init | "false" | installs automatically | Script-tag-only: suppresses the automatic install on DOM ready so the host can call window.ForeloopFeedback.init({…}) itself. |

What the widget submits

Opening the widget shows two categories — Automatic bug fix and Automatic product improvement (a support category exists but is not yet listed). The chosen category configures the form (the bug category adds a Priority field) and is recorded in the signal's body_markdown as - Category: <label> under Widget context. Signals are kind: "user_feedback" with sanitized page context, optional element annotations (selector + note), and an optional screenshot uploaded as an attachment after the signal is created. Filter downstream on the Category: line for routing.

Behavior notes for integrators

  • Launcher tone: the floating launcher samples the page background under itself (solid colors and gradient end-stops) and flips between the dark and light icon variants on scroll/resize/theme changes. buttonColor theming rides on top of this.
  • Dismissal: clicking outside closes the panel only from the category menu; a form with typed content is never dismissed by a stray click (Escape, Cancel, and ✕ always work).
  • Re-initialization: calling init again fully replaces the widget with the new options — safe to call on auth changes or SPA navigation.

Supply chain

This package has no runtime dependencies — not a small tree, an empty one. A clean install adds exactly one package:

$ npm install @foreloop/feedback
added 1 package, and audited 2 packages
found 0 vulnerabilities

If npm audit reports advisories after installing it, they come from something else in that node_modules tree. npm ls <package> prints the dependency path to whatever actually pulled the vulnerable package in.

Releases are published from GitHub Actions. They do not carry npm provenance attestations, because npm only accepts provenance from public source repositories and this repository is private.

Privacy defaults

  • URL query strings and fragments are excluded unless includeQuery is enabled.
  • Inputs, editable content, and elements marked data-private, data-sensitive, or data-foreloop-private can never be selected as annotations.
  • Screenshots are optional and always go through the browser's own consent.
  • Reporter identity is supplied by the host; the widget never infers it.