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

@joy-loyalty/weaverse-hydrogen

v0.2.0

Published

Joy Loyalty blocks for Weaverse Hydrogen storefronts (drag-and-drop sections backed by the Joy Headless API)

Readme

@joy-loyalty/weaverse-hydrogen

Joy Loyalty blocks for Weaverse Hydrogen storefronts. Adds a Joy - Loyalty Page block to Weaverse Studio that renders the same Loyalty Page V2 core the Joy Liquid storefront runs, so styling is done once, in the Joy admin.

Built on @joy-loyalty/hydrogen and @joy-loyalty/sdk. Version 0.2.0 replaced the earlier nine React blocks with this single block; see CHANGELOG.md before upgrading.

ESM-only. Peers: @weaverse/hydrogen ^5.19.2, react 18/19, react-router ^7, @shopify/hydrogen >= 2025.5 (optional).

Prerequisites

  • A Joy Loyalty store on the Ultimate plan (the Headless API is plan-gated).
  • A Weaverse Hydrogen storefront with Customer Account API login.
  • The headless API secret from your Joy admin.

Install

npm install @joy-loyalty/weaverse-hydrogen @joy-loyalty/hydrogen @joy-loyalty/sdk

Environment variables

| Variable | Where | Notes | |---|---|---| | JOY_API_URL | server | e.g. https://api.joy.so/app/api/v1/headless. Not a credential. | | JOY_SHOP_DOMAIN | server | The shop's *.myshopify.com domain. | | JOY_API_SECRET | server only | The headless API secret from your Joy admin. | | JOY_WIDGET_ASSET_URL | optional | Overrides the widget-core origin (default https://static.joy.so). |

Warning: server-only secret. JOY_API_SECRET must only be read on the server (Oxygen loaders and resource routes). Never prefix it PUBLIC_ or VITE_, never return it from a loader, and never import code that reads it into a client bundle.

Note: the secret will be rotated to a dedicated headless secret before general availability. The variable name stays JOY_API_SECRET.

Setup

1. Register the block

// app/weaverse/components.ts
import {joyComponents} from '@joy-loyalty/weaverse-hydrogen';

export const components: HydrogenComponent[] = [...pilotComponents, ...joyComponents];

2. Token route

// app/routes/api.joy-token.ts
export {loader} from '@joy-loyalty/weaverse-hydrogen/routes/joy-token';

3. Optional place-order scope route (only for place_order programs restricted to products/collections)

// app/routes/api.joy-place-order-scope.ts
export {loader} from '@joy-loyalty/weaverse-hydrogen/routes/joy-place-order-scope';

4. Root loader and provider. The block reads the root loader's joy key. Build it with getJoyInitialData from @joy-loyalty/hydrogen/server (see the @joy-loyalty/hydrogen README) and, if your app does not wire cart state otherwise, wrap your content in JoyProvider.

5. CSP — use the directives from @joy-loyalty/hydrogen/csp:

import {JOY_CSP_DIRECTIVES} from '@joy-loyalty/hydrogen/csp';

createContentSecurityPolicy({
  scriptSrc: ['self', ...JOY_CSP_DIRECTIVES.scriptSrc],
  connectSrc: ['self', ...JOY_CSP_DIRECTIVES.connectSrc],
  styleSrc: ['self', ...JOY_CSP_DIRECTIVES.styleSrc],
  imgSrc: ['self', ...JOY_CSP_DIRECTIVES.imgSrc]
});

For a custom asset/API host use joyCspDirectives({apiUrl, assetUrl}).

Caching

Use isJoyBlockDataPersonalized and JOY_PERSONALIZED_CACHE_CONTROL (exported here) to set Cache-Control: private on pages whose Joy data is personalized.

Exports

joyComponents, JoyLoyaltyPage, JoyLoyaltyWidget, JoyProvider, useJoyConfig, useJoyCustomer, getJoyToken, clearJoyToken, DEFAULT_TOKEN_ROUTE, isJoyBlockDataPersonalized, JOY_PERSONALIZED_CACHE_CONTROL. Subpaths: /routes/joy-token, /routes/joy-place-order-scope. Note joyComponents contains only the Loyalty Page block; JoyLoyaltyWidget is exported for custom registration.

Security notes

  • The customer JWT is kept in sessionStorage (about 1 hour TTL), so XSS on your storefront can read it. Keep a strict CSP.
  • The widget core is loaded from static.joy.so (override with JOY_WIDGET_ASSET_URL); allow-list only trusted origins.
  • The token route answers Cache-Control: private, no-store.

License

Proprietary. Copyright (c) 2026 Avada Group. All rights reserved. Licensed only for use with the Joy Loyalty service under the Joy Loyalty Terms of Service. See LICENSE.