@gridd/docusaurus-feedback-plugin
v0.3.5
Published
Docusaurus plugin that injects Feedback Stickers into every page and handles SPA navigation
Maintainers
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
- Save the received
.htmlfile anywhere on the computer and open it in a browser (Chrome, Firefox, or Safari). No internet connection required. - Click the 📌 button (bottom-right corner).
- Enter a name or initials in the Reviewer field.
- Pick a color to categorise the feedback (labels are customisable).
- Click Start Reviewing — the cursor changes to a crosshair.
- Click anywhere on the page to place a sticky note.
- Type a comment in the note.
- Repeat across the page, switching colors as needed.
- 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
- Open the Docusaurus site and navigate to the reviewed page.
- Click the 📌 button → Import YAML and select the received
.review.yaml. - 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 buildAdd 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-pluginConfigure
// 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:
- Deep-clones
document.documentElement - Removes navigation chrome (
nav,aside,footer, sidebar/navbar/pagination class fragments,[role="navigation"], etc.) - Fetches every linked stylesheet, inlines
url()assets (fonts, background images) as base64 data URIs, and replaces<link>with<style> - Processes remaining inline
<style>blocks the same way - Fetches every
<img src>and replaces it with a base64 data URI; removessrcsetandloadingattributes - Locates the feedback-stickers IIFE already running on the page and appends it to the cloned
<body> - 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