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

@whatworks/analytics

v1.0.4

Published

Analytics components for Next.js with cookie consent.

Readme

NextJS Analytics

 

Analytics components for Next.js (App Router) with built-in cookie consent. Most vendor snippets assume a full page reload on every navigation, so when you drop them straight into layout.tsx the initial page view fires but client-side route changes are never tracked — you end up with a single hit per session. This package wraps the tracking scripts most projects need — Google Analytics, Google Tag Manager, Facebook Pixel, Microsoft Clarity, and LinkedIn Insight Tag — in components that load via next/script and re-fire page views off usePathname as the user navigates, all gated through a shared consent provider that can optionally require consent by geolocation (EEA / UK / CH).

Contents

Installation

pnpm add @whatworks/analytics

Peer deps: next >= 13.4, react >= 18.2.

Usage

1. Add the consent API route

The provider needs an endpoint that returns whether the current request requires consent. A default handler is exported that uses Vercel's x-vercel-ip-country header to flag EEA / UK / CH visitors.

// app/api/consent/route.ts
export { GET } from '@whatworks/analytics/api/consent'

If you aren't on Vercel, write your own handler that returns { requiresConsent: boolean }.

2. Render <Analytics> in your root layout

// app/layout.tsx
import { Analytics, CookieBanner } from '@whatworks/analytics'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Analytics />
        {children}
        <CookieBanner />
      </body>
    </html>
  )
}

<Analytics> is a no-op outside of NODE_ENV === 'production'.

3. Configure IDs

Each script is only rendered when its ID is present. Pass IDs as props, or set the matching env var:

| Prop | Env var | | ------------------- | ------------------------------------ | | gaId | NEXT_PUBLIC_GOOGLE_ANALYTICS_ID | | gtmId | NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID | | facebookPixelId | NEXT_PUBLIC_FACEBOOK_PIXEL_ID | | clarityId | NEXT_PUBLIC_MS_CLARITY_ID | | linkedInPartnerId | NEXT_PUBLIC_LINKEDIN_PARTNER_ID |

<Analytics gaId="G-XXXX" linkedInPartnerId="1234567" />

Consent strategies

CookieBannerProvider accepts a consentStrategy prop. <Analytics> defaults to load-scripts-then-revoke-consent-after-geolocation-check — good for most marketing sites. If you want finer control, compose the pieces yourself:

import {
  CookieBannerProvider,
  CookieBanner,
  GoogleAnalytics,
  GtagBootstrap,
} from '@whatworks/analytics'

<CookieBannerProvider
  consentApiPath="/api/consent"
  consentStrategy="require-consent-before-loading-scripts"
>
  <GtagBootstrap />
  <GoogleAnalytics gaId="G-XXXX" />
  <CookieBanner />
</CookieBannerProvider>

| Strategy | Scripts load | Default consent | Banner shown | | --- | --- | --- | --- | | load-scripts-always-grant-consent | immediately | granted | never | | load-scripts-revoke-consent-immediately | immediately | denied | if geolocation requires it | | load-scripts-then-revoke-consent-after-geolocation-check | immediately | granted until geo check | if geolocation requires it | | require-consent-before-loading-scripts | only after consent | denied | if geolocation requires it |

Components

  • <Analytics> — top-level composition. Renders the provider and every tag whose ID is present.
  • <CookieBanner> — default banner UI with title, description, acceptText, rejectText props. Only visible when the provider decides it should be.
  • <CookieBannerProvider> / useCookieBanner() — consent context. Exposes consentStatus, shouldLoadScripts, shouldShowBanner, accept(), reject().
  • <GtagBootstrap> — shared dataLayer + gtag stub and Consent Mode state. Render once when using either GA or GTM.
  • <GoogleAnalytics gaId> — GA4 config script.
  • <GoogleTagManager gtmId> — GTM container script.
  • <FacebookPixel pixelId> — Meta Pixel with SPA route tracking and noscript fallback.
  • <MicrosoftClarity clarityId> — Clarity with consent v2 signalling. You must disable cookies in the Clarity dashboard for GDPR compliance — see Clarity's docs.
  • <LinkedInInsightTag partnerId> — LinkedIn Insight Tag, consent-gated. Loads only once consent is granted (LinkedIn has no native consent API).

Notes

  • If your GTM container includes a GA4 Configuration tag for the same property as gaId, page_view events will be double-counted. Pick one side.
  • The default CookieBanner renders into a portal and links to /privacy-policy — pass a custom description to override.
  • All script components are 'use client'; <Analytics> itself is a server component.