Getting started
-
Install the package.
npm install penciledpnpm add penciledyarn add penciledbun add penciled -
Call
annotate()on the element that holds your content, and import the default styles.import { annotate } from 'penciled';import 'penciled/styles.css';annotate('#article');annotate()accepts a CSS selector or an element. Readers can now select text inside it to highlight it in one of five colors, add a note, or click a highlight to change it. -
Reload the page. Annotations are saved to
localStorageas they change and restored when the page loads. No backend is needed.
The styles
Section titled “The styles”penciled/styles.css holds the toolbar, the note editor and the highlight colors. Import it once, from JavaScript as above or from CSS:
@import 'penciled/styles.css';Its selectors have zero specificity, so your own CSS wins. Only penciled’s buttons and note field carry one attribute, so element resets like Tailwind’s preflight can’t strip them. See Theming and customization.
Name the document
Section titled “Name the document”Annotations are stored under a document id. By default it is the page’s pathname, plus the container’s id when it has one. In development penciled warns about this default, because in single-page apps the URL doesn’t always identify the content. Pass your own id when the same page can show different content:
annotate('#article', { documentId: `post-${post.slug}` });Keep the instance
Section titled “Keep the instance”annotate() returns an instance for reading and changing annotations, listening to events and cleaning up:
const penciled = annotate('#article', { onCreate: (annotation) => console.log('Highlighted', annotation.quote),});
penciled.getAll(); // every annotation, in document orderpenciled.export(); // { version, documentId, annotations }penciled.destroy(); // removes highlights, UI and listenersSee Instance for every method.
Server-side rendering
Section titled “Server-side rendering”Importing penciled is safe on the server: nothing touches window or document until annotate() runs. Call annotate() in the browser only, for example in an effect or a client-side script. In React, use the React adapter.