Skip to content
 
 

Repository files navigation

annotate-plus

Fork of reviewjs with enhancements for production use.

What's new in this fork

Google Sheets sync

Optionally sync comments to a Google Sheet in real time. The sheet doubles as a live review dashboard — every annotation appears as a row, and any collaborator with access to the sheet can see, filter, and sort feedback without installing anything.

Setup

  1. Create a Google Sheet with this header row:

    annotateId | page | url | type | author | text | color | anchor | geom | resolved | parentId | createdAt | updatedAt

    The Sheet doesn't need to be shared with reviewers — the Apps Script runs as you and writes to it directly. Just make sure the Sheet stays in your Google Drive (the script needs access to it). If you want your team to view feedback directly in the Sheet, share it with them as Viewer (or Commenter if they should add notes). Reviewers on your website never touch the Sheet directly — only the Apps Script does.

  2. Extensions → Apps Script, paste the contents of google-sheet.gs, and save.

  3. Deploy → New deployment → Web app:

    • Execute as: Me
    • Who has access: Anyone
    • Copy the web app URL. The production URL always ends with /exec — do not use a /dev URL (those are dev deployments only accessible to the script owner).
  4. Set the URL with data-google-sheet="<URL>" on the script tag — reviewers never see a setup prompt. Comments push/pull automatically.

Once connected, comments are pushed to the sheet automatically — create, edit, reply, and delete all sync within a few seconds. Comments from other reviewers on the same sheet appear when you load the page.

A Sync now button in the comments panel footer lets you force a pull at any time. Click Change in the footer to switch sheets.

No Google account required for reviewers. The Apps Script runs as the sheet owner. Reviewers only need the web app URL.


Other enhancements

  • CORS fixgsPull GET requests no longer send an unnecessary Content-Type header that triggered OPTIONS preflight (405 from Google Apps Script). POST requests use text/plain instead of application/json to avoid preflight entirely.
  • Stale GS_URL fix — sheet URL changes made via the dialog now actually take effect. Previously the module-level variable was set once at init and never updated.
  • Cancel / close on sheet modal — clicking outside, pressing Escape, or clicking "Cancel" dismisses the Google Sheets configuration dialog without changing existing settings.
  • Customizable launcher text — the floating Review pill can be customized (currently reads "Review & Add Feedback to website").

Original readme


reviewjs

A Visual screenshot of Annotatejs A drop-in visual review & annotation layer for any website. Highlight text, draw rectangles & circles, drop pins, sketch freehand and leave threaded comments — directly on top of your live page.

No backend. No database. No tracking. Comments live in the visitor's own browser (localStorage) and can be downloaded to / imported from a portable JSON file to share with your team.

<script src="https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js" defer></script>

That single line is the whole installation.


Why reviewjs?

  • One <script> tag. No build step, no framework, no signup.
  • Works everywhere. Plain HTML, React, Vue, Svelte, WordPress, Webflow, Shopify, static sites — anything that renders HTML in a browser.
  • Local-first & private. Every comment is stored on the reviewer's device. Nothing is sent anywhere.
  • Portable. Reviewers export their feedback as JSON and send it to you; you import it with one click and see every note in place.
  • Polished UI. A floating toolbar, a Figma-style comments panel, light/dark themes that auto-adapt to your page, and full keyboard shortcuts.
  • Tiny & dependency-free. ~40 KB of vanilla JavaScript, zero dependencies.

Features

Tool What it does
✏️ Highlight Select any text to highlight and comment on it
Rectangle Draw a box around any region
Circle Circle anything that needs attention
📍 Pin Drop a point marker anywhere
〰️ Freehand Sketch directly on the page
Section note Hover any paragraph/heading for a margin comment button

Plus: threaded replies, resolve/reopen, search & filter, deep-links to a single comment (#an=<id>), an "off" mode that collapses to a small launcher, and a Download / Import round-trip for sharing.


Quick start

1. The fastest way (CDN)

Add this just before </body>:

<script src="https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js" defer></script>

That's it — reload the page and the toolbar appears in the bottom-right corner.

Pin a version for production stability: https://cdn.jsdelivr.net/npm/@reviewjs/annotate@1.0.1/annotate.js

unpkg works too: https://unpkg.com/@reviewjs/annotate@1.0.1/annotate.js

2. Self-hosted

Download annotate.js, drop it next to your HTML and:

<script src="/annotate.js" defer></script>

Configuration

Configure with data- attributes on the script tag — all optional:

<script
  src="https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js"
  data-project="marketing-site"
  data-accent="#6d28d9"
  data-theme="auto"
  data-position="bottom-right"
  data-start-open="true"
  data-note="Focus on the hero copy and pricing — flag anything off-brand."
  data-share-email="reviews@example.com"
  defer
></script>
Attribute Default Description
data-project "" Namespace for stored comments. Keep separate sites apart.
data-page location.pathname Page key comments are grouped under.
data-accent Brand color for primary buttons & the active tool.
data-theme auto light, dark, or auto (sniffs your page background).
data-position bottom-right bottom-right or bottom-left.
data-blocks sensible default CSS selector for "section note" (+) targets.
data-start-open false Set to true to show the review toolbar immediately instead of the collapsed Review pill.
data-note Author's note to reviewers — what should be reviewed. Shown when they start and atop the comments panel.
data-share-email Where reviewers send comments: an email address, or a Slack / Hangout link. Adds a Share button.
data-google-sheet Deployed Google Apps Script web app URL for auto-sync. Reviewers are prompted for this on first use if not set.

Prefer JS config? Set window.AnnotateConfig before the script loads:

<script>
  window.AnnotateConfig = {
    project: "marketing-site",
    accent: "#6d28d9",
    theme: "auto",
    note: "Focus on the hero copy and pricing — flag anything off-brand.",
    shareEmail: "reviews@example.com",
  };
</script>
<script src="https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js" defer></script>

Framework integration

reviewjs is a plain browser script, so the goal everywhere is the same: load annotate.js once, after the page has rendered. Below are copy-paste recipes.

⚛️ React (and Next.js)

Load it once at the app root with a useEffect:

// components/Annotate.jsx
import { useEffect } from "react";

export default function Annotate() {
  useEffect(() => {
    if (document.getElementById("annotate-js")) return;
    window.AnnotateConfig = { project: "my-react-app", accent: "#6d28d9" };
    const s = document.createElement("script");
    s.id = "annotate-js";
    s.src = "https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js";
    s.defer = true;
    document.body.appendChild(s);
  }, []);
  return null;
}
// App.jsx
import Annotate from "./components/Annotate";

export default function App() {
  return (
    <>
      <Annotate />
      {/* your app */}
    </>
  );
}

Next.js (App Router) — drop the <Script> into app/layout.js:

import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

🟩 Vue 3

<!-- App.vue -->
<script setup>
import { onMounted } from "vue";

onMounted(() => {
  if (document.getElementById("annotate-js")) return;
  window.AnnotateConfig = { project: "my-vue-app", accent: "#10b981" };
  const s = document.createElement("script");
  s.id = "annotate-js";
  s.src = "https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js";
  s.defer = true;
  document.body.appendChild(s);
});
</script>

Or, even simpler, add the <script> tag straight into public/index.html (Vue CLI) / index.html (Vite) before </body>.

🧩 WordPress

Option A — no code. Install a "header/footer scripts" plugin (e.g. WPCode or Insert Headers and Footers) and paste this into the footer box:

<script src="https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js" data-project="my-wp-site" defer></script>

Option B — theme code. Add to your theme's functions.php:

function reviewjs_enqueue() {
  wp_enqueue_script(
    'reviewjs',
    'https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js',
    array(),
    '1.0.1',
    true // load in footer
  );
}
add_action( 'wp_enqueue_scripts', 'reviewjs_enqueue' );

Tip: wrap the enqueue in if ( current_user_can('edit_posts') ) to show the review tools only to logged-in editors.

🔷 Svelte / SvelteKit

<!-- src/routes/+layout.svelte -->
<script>
  import { onMount } from "svelte";
  onMount(() => {
    const s = document.createElement("script");
    s.src = "https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js";
    s.defer = true;
    document.body.appendChild(s);
  });
</script>

<slot />

🅰️ Angular

In angular.json, add to the "scripts" array:

"scripts": [
  "https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js"
]

🌐 Plain HTML / static sites / Webflow / Shopify / Squarespace

Paste before </body> (or into the platform's "custom code / footer" field):

<script src="https://cdn.jsdelivr.net/npm/@reviewjs/annotate/annotate.js" defer></script>

Sharing comments

Because everything is local, sharing is an explicit, privacy-friendly action:

  1. A reviewer opens the Comments panel (toolbar list icon or press A).
  2. They click Download (⬇) to save a annotate-<page>-<date>.json file.
  3. They send you that file.
  4. You open the same page, click Import (⬆), pick the file — every comment reappears anchored in place.

You can also drive this from code (see the API below).

JavaScript API

A global window.Annotate is available once the script loads:

Annotate.open();              // show the review layer and open the comments panel
Annotate.close();
Annotate.toggle();
Annotate.enable();            // show the review layer
Annotate.disable();           // collapse to the launcher
Annotate.setTool("highlight");// show the layer, then choose cursor | highlight | rect | circle | pen | pin
Annotate.comments();          // → array of comment objects for this page
Annotate.focus(id);           // scroll to & highlight a comment
Annotate.export();            // trigger the JSON download
Annotate.import();            // open the file picker
Annotate.clear();             // delete all comments on this page (local)
Annotate.toast("Saved!");     // show a toast
Annotate.version;             // "1.0.1"

Comment shape

{
  "id": "c…",
  "page": "marketing-site:/pricing",
  "url": "https://example.com/pricing",
  "type": "highlight",
  "author": "Jane Doe",
  "text": "This price looks out of date.",
  "color": "#f59e0b",
  "anchor": { "exact": "", "prefix": "", "suffix": "" },
  "geom": null,
  "resolved": false,
  "replies": [],
  "createdAt": "2026-06-16T10:00:00.000Z",
  "updatedAt": "2026-06-16T10:00:00.000Z"
}

Keyboard shortcuts

Key Action Key Action
V Browse P Pin
H Highlight A Comments panel
R Rectangle O Show / hide tools
C Circle Esc Cancel
D Freehand ? Shortcuts card

Try it locally

git clone git@github.com:reviewjs/annotate.git
cd annotate
npm start          # serves the demo at http://localhost:3000

Open index.html and start annotating. Framework examples live in examples/.


Browser support

Modern evergreen browsers (Chrome, Edge, Firefox, Safari). Uses standard DOM APIs only — no polyfills required. Gracefully no-ops where localStorage is unavailable (private mode, sandboxed iframes).


License

MIT — free for personal and commercial use.

About

Fork of https://reviewjs.github.io/annotate/

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages