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

@gridd/docusaurus-feedback-plugin

v0.3.5

Published

Docusaurus plugin that injects Feedback Stickers into every page and handles SPA navigation

Readme

@gridd/docusaurus-feedback-plugin

Adds a two-button toolbar to every page of a Docusaurus site:

| Button | What it does | |---|---| | ⬇ (green) | Exports the current page as a single self-contained HTML file — no server required to open it | | 📌 (dark) | Opens the sticker panel for placing, managing, importing and exporting review annotations |

The intended review flow uses the ⬇ button to generate a shareable HTML snapshot. The reviewer opens it locally, annotates it with stickers, and sends back a .review.yaml file — no Docusaurus installation, no dev server, no account needed on either side.


Review workflow

Step 1 — Author: export the page

Navigate to the page you want reviewed and click the ⬇ button.

The browser downloads <page-title>.html — a fully self-contained file with:

  • all page CSS inlined (fonts, icons, syntax highlighting)
  • all images base64-encoded
  • the feedback stickers panel embedded
  • no external dependencies

Send this single .html file to the reviewer.


Step 2 — Reviewer: open and annotate

  1. Save the received .html file anywhere on the computer and open it in a browser (Chrome, Firefox, or Safari). No internet connection required.
  2. Click the 📌 button (bottom-right corner).
  3. Enter a name or initials in the Reviewer field.
  4. Pick a color to categorise the feedback (labels are customisable).
  5. Click Start Reviewing — the cursor changes to a crosshair.
  6. Click anywhere on the page to place a sticky note.
  7. Type a comment in the note.
  8. Repeat across the page, switching colors as needed.
  9. Click Stop Reviewing when done.

Step 3 — Reviewer: export annotations

In the 📌 panel, click Export YAML.

A file named <page-title>.review.yaml is downloaded. Send it back to the author (email, Slack, PR attachment — anything works).


Step 4 — Author: view the review

  1. Open the Docusaurus site and navigate to the reviewed page.
  2. Click the 📌 button → Import YAML and select the received .review.yaml.
  3. The reviewer's stickies appear on the page, each anchored to the element it was placed on.

To collect feedback from several reviewers, import their files one after the other. Stickers from different reviewers are merged by ID — importing the same file twice is safe.


Why this approach

| Concern | How it is addressed | |---|---| | Reviewer has no Docusaurus access | The exported HTML is fully self-contained and opens offline | | Page looks different at reviewer's screen size | Stickers use anchor + percentage coordinates — they re-attach to the correct element regardless of viewport width | | Reviewer annotates wrong version | The export captures an exact snapshot at export time | | Multiple reviewers | Import YAML files one at a time; sticker IDs prevent duplication | | Sensitive content | Everything stays in files exchanged directly between people — nothing is uploaded to any service |


Installation

Prerequisites

Build the core package first — the plugin copies its compiled output.

# from the repo root
npm install && npm run build

cd plugin
npm install && npm run build

Add to a Docusaurus project

# local path (monorepo / development)
npm install --save-dev /path/to/gridd-docusaurus-feedback-plugin/plugin

# or once published to npm
npm install --save-dev @gridd/docusaurus-feedback-plugin

Configure

// docusaurus.config.js
module.exports = {
  plugins: [
    '@gridd/docusaurus-feedback-plugin',
  ],
};

With options:

plugins: [
  [
    '@gridd/docusaurus-feedback-plugin',
    {
      devOnly: true,  // hide the panel in production builds
    },
  ],
],

| Option | Type | Default | Description | |---|---|---|---| | enabled | boolean | true | Master switch — false removes the panel without touching the rest of config | | devOnly | boolean | false | Only inject during docusaurus start; production builds get no sticker code |


How the plugin works technically

Injection

injectHtmlTags appends the full feedback-stickers IIFE as an inline <script> to every page's <body>. This guarantees the panel initialises before any client-side hydration runs.

SPA navigation

Docusaurus navigates between pages client-side without full reloads. The plugin registers a client module (via getClientModules) that Docusaurus's webpack bundles into the site JS. It exports onRouteDidUpdate — a Docusaurus hook called after every route change — which calls window.__feedbackStickers.refresh().

refresh() stops reviewing mode, removes the previous page's stickers from the DOM, and loads and renders stickers for the new URL from localStorage.

Page export

The ⬇ button triggers an async pipeline in the browser:

  1. Deep-clones document.documentElement
  2. Removes navigation chrome (nav, aside, footer, sidebar/navbar/pagination class fragments, [role="navigation"], etc.)
  3. Fetches every linked stylesheet, inlines url() assets (fonts, background images) as base64 data URIs, and replaces <link> with <style>
  4. Processes remaining inline <style> blocks the same way
  5. Fetches every <img src> and replaces it with a base64 data URI; removes srcset and loading attributes
  6. Locates the feedback-stickers IIFE already running on the page and appends it to the cloned <body>
  7. Serialises to <!DOCTYPE html>\n<html>…</html> and triggers a browser download

Architecture diagram

docusaurus.config.js
  └── @gridd/docusaurus-feedback-plugin
        ├── dist/index.js          Node.js — runs at Docusaurus build time
        │     ├── injectHtmlTags() → <script> feedback-stickers.min.js </script>
        │     └── getClientModules() → registers dist/client.js
        │
        └── dist/client.js         Browser — bundled by Docusaurus webpack
              └── onRouteDidUpdate() → window.__feedbackStickers.refresh()

feedback-stickers.min.js  (~21 KB, embedded in every page)
  ├── 📌 sticker panel
  ├── ⬇ page export button
  └── window.__feedbackStickers = { refresh }

Development

# watch mode for the plugin TypeScript
cd plugin && npm run dev

# after changing src/ in the core package, rebuild the full chain:
cd ..      && npm run build   # rebuilds feedback-stickers.min.js
cd plugin  && npm run build   # recompiles TS and copies the new IIFE