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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@sunnysideup/npm-page-favourites-bookmarker

v2.0.4

Published

NPM package - to bookmark / favourite any page on a website

Readme

@sunnysideup/npm-page-favourites-bookmarker

Tiny in-page bookmark manager with a heart button, overlay list, and optional server sync including a "share list" functionality.

Features

  • Heart button on every page to toggle bookmark (saves URL, title, image and description).

  • Overlay list of favourites (hotkey toggle), with remove and drag-to-sort.

  • Uses local storage or session storage.

  • Optional server sync:

    • Sends events on add/remove/sort.
    • If logged in, it can sync with existing list from user
  • Very limited dependencies, plain ESM.

Install

npm i  @sunnysideup/npm-page-favourites-bookmarker

Usage

with a bundler (Vite/Webpack/Rollup)

import { PageFaves } from '@sunnysideup/npm-page-favourites-bookmarker';
@import "@sunnysideup/npm-page-favourites-bookmarker/styles";

without a bundler (Vite/Webpack/Rollup)

Check where node_modules lives ...and then add this (with additional path segments, if needed).

<link rel="stylesheet" href="/node_modules/@sunnysideup/npm-page-favourites-bookmarker/src/index.css">
<script type="module">
  import { PageFaves } from '/node_modules/@sunnysideup/npm-page-favourites-bookmarker/src/index.js'
</script>

initialising the module (with or without a bundler (Vite/Webpack/Rollup))

Initialising the module

import { PageFaves } from '@sunnysideup/npm-page-favourites-bookmarker'

const pf = new PageFaves({
  baseUrl: 'https://api.example.com/my-controller', // enables server I/O

})
document.addEventListener('DOMContentLoaded', () => {
  pf.init()
})

making the api available in the global space

import { PageFaves } from '@sunnysideup/npm-page-favourites-bookmarker'

window.myPageFavourites = new PageFaves({
  baseUrl: 'https://api.example.com/my-controller', // enables server I/O
  loginUrl: '/my-account',
})
document.addEventListener('DOMContentLoaded', () => {
  window.myPageFavourites.init()
})

Config options

To see the config options (and there are many), you can have a look at this file:

main configs - see DEFAULTS

with the main config you can also set alternatives for these:

templates html classes phrases (translations)

Per-page configuration (page wins)

Add a small script before you import/initialise and you can set any of the configs above on a page by page basis

<script>
  window.npmPageFavouritesBookmarkerConfig = {
    // whether to render on this page (overrides defaults and constructor opts)
    loadOnThisPage: true,
    // login awareness for overlay
    userIsLoggedIn: false,
    // optional positioning overrides
    heartPositionLeftRight: 'right',
    heartPositionTopBottom: 'bottom',
    currentPageTitle: document.querySelector('h2.title')?.innerText || ''
    currentImagelink: document.querySelector('meta[property="og:image"]')?.content || ''
    currentDescription: document.querySelector('meta[property="og:description"]')?.content || ''
    phrases: {
      favouritesTitle: 'My Favourite blog entries',
      noBookmarksText: 'You do not have any favourites yet. To add some, on any page, click on the ❤ icon on the bottom right of your screen.'
    }
  }
</script>

Adding snippets directly to your page

If the following class pf-heart-for-current-page is present on the page then the heart will be added in this holder and not as per usual as the last element to the body.


<div class="pf-heart-for-current-page"></div>

You can also add "add to favourites" for other pages on the page (e.g. when you have a list of links to other pages).

This can be done as follows:


<div class="pf-heart-for-another-page" data-pf-url="..." data-pf-title="..." data-pf-description="..." data-pf-imagelink="..." ></div>

where ... is a different value for each page (description and imagelink are optional)

Hotkeys

  • Open overlay: CTRL + SHIFT + B (uses overlayHotkey: 'KeyB').
  • Close overlay: ESC.

Server sync behaviour

No network calls are made unless baseUrl is provided.

On init(), if syncLoggedInUsersToServer is true and userIsLoggedIn is true, the client pulls favourites from {bookmarks} and replaces them with local.

This initial pull is run whenever the number of favourites on the server is not the same as the local ones.

Every add/remove/reorder triggers a POST {events}.

API

General methods

  • updateScreen → align all the hearts on the page.

Bookmark methods

  • addCurrent → add a bookmark for the current page.
  • removeCurrent → remove bookmark for the current page.
  • toggleCurrent → toggle bookmark for the current page.
  • isBookmarked(url) → check if URL is bookmarked
  • toggleFromData(el) → add a bookmark for another page (see above for structure of el)
  • add(url, title, imagelink, description) → add a bookmark
  • remove(url) → remove bookmark

List and overlay

  • list() → get all favourites
  • getLocalBookmarkCount() → get a count of local bookmarks
  • toggleOverlay() → show or hide overlay (showing all favourites)
  • showOverlay() → show overlay
  • hideOverlay() → hide overlay

Server Related

  • syncFromServer() → pull bookmarks and and merge with local (only if baseUrl set)
  • copyShareLink() → copy sharelink to clipboard

clear and destroy

  • clear() → remove all bookmarks
  • destroy → the opposite of init - remove ALL and reset all

Server Endpoints

You can override each endpoint individually in endpoints.

  • POST {events}{ type, payload, at } (types are add/remove/reorder)
  • GET {bookmarks}[{ url, title, imagelink, description, ts }]

Back-end Server Integration

If you use Silverstripe CMS, check out the integration package:

sunnysideup/silverstripe-page-favourites-bookmarker