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

@flash-analytics/nextjs

v2.2.0

Published

## Local development

Readme

Flash Analytics Next.js SDK

Local development

If you want to test the Next.js SDK against local Flash Analytics services, point:

  • the API endpoint to http://localhost:3333
  • the loader script to http://localhost:3000/fa1.js

Example with the App Router:

import { FlashAnalyticsComponent } from '@flash-analytics/nextjs';

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="en">
      <body>
        <FlashAnalyticsComponent
          appId="your-app-id"
          endpoint="http://localhost:3333"
          scriptUrl="http://localhost:3000/fa1.js"
          capturePageViews
          captureErrors       // js_error + unhandled_promise_rejection
          captureVariants     // auto-assign experiments on session + identify
        />
        {children}
      </body>
    </html>
  );
}

Example with the Pages Router:

import type { AppProps } from 'next/app';
import { FlashAnalyticsComponent } from '@flash-analytics/nextjs';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <FlashAnalyticsComponent
        appId="your-app-id"
        endpoint="http://localhost:3333"
        scriptUrl="http://localhost:3000/fa1.js"
        capturePageViews
      />
      <Component {...pageProps} />
    </>
  );
}

If your app uses client helpers, import them normally:

'use client';

import { useFlashAnalytics } from '@flash-analytics/nextjs';

export function ExampleButton() {
  const analytics = useFlashAnalytics();

  return (
    <button onClick={() => analytics.track('button_clicked')}>
      Track
    </button>
  );
}

Using the local package

If your Next.js app is outside this monorepo, build and link the local SDK packages first (run from the monorepo root):

pnpm --filter @flash-analytics/sdk build
pnpm --filter @flash-analytics/web build
pnpm --filter @flash-analytics/nextjs build
pnpm --filter @flash-analytics/sdk link --global
pnpm --filter @flash-analytics/web link --global
pnpm --filter @flash-analytics/nextjs link --global

Then in your Next.js app:

pnpm link --global @flash-analytics/sdk
pnpm link --global @flash-analytics/web
pnpm link --global @flash-analytics/nextjs

When you change SDK code locally, rebuild the packages so your app picks up the latest output (from the monorepo root):

pnpm --filter @flash-analytics/sdk build
pnpm --filter @flash-analytics/web build
pnpm --filter @flash-analytics/nextjs build

Route handler note

The Next.js route handler can proxy API requests to a custom endpoint:

import { createRouteHandler } from '@flash-analytics/nextjs/server';

export const { GET, POST } = createRouteHandler({
  endpoint: 'http://localhost:3333',
});

Use this only for API proxying. The built-in /fa1.js proxy still fetches the script from the production dashboard, so for local dashboard development you should set scriptUrl="http://localhost:3000/fa1.js" on FlashAnalyticsComponent.

Experiment Auto-Assignment

Add captureVariants to <FlashAnalyticsComponent> to automatically keep a local cache of experiment assignments in sync:

<FlashAnalyticsComponent
  appId="your-app-id"
  captureVariants  // shorthand for captureVariants={true}
/>

How the local cache is maintained

Session start (new session ID received from /track): Fetches ALL experiments — profile, session, and event-triggered — and replaces the entire local store. Only fires when the session ID actually changes; repeated track() calls on the same session do not re-fetch.

After identify(): Fetches only profile-mode experiments (user identity just changed) and replaces only the profile-mode entries in the store. Session and event assignments are left untouched.

Session expiry: Removes only session-mode assignments when the cached session TTL runs out. Profile and event assignments survive.

Reading assignments

'use client';

import { useFlashAnalytics } from '@flash-analytics/nextjs';

export function PricingBanner() {
  const analytics = useFlashAnalytics();

  // All cached assignments — no API call
  const all = analytics.getAllExperiments();

  // Single experiment — checks cache first, falls back to API if not found
  const assignment = await analytics.getExperimentById('checkout-cta');
  console.log(assignment?.variantName);
}

Local store state at each lifecycle point

| Moment | Profile assignments | Session assignments | Event assignments | |---|---|---|---| | After first track() (new session) | fetched | fetched | fetched | | After identify() | re-fetched | unchanged | unchanged | | After session expiry | unchanged | removed | unchanged | | After next track() (new session) | re-fetched | re-fetched | re-fetched |

Session access

If you are using the browser helpers:

'use client';

import { useFlashAnalytics } from '@flash-analytics/nextjs';

const analytics = useFlashAnalytics();
const session = analytics.getSession();

console.log(session?.id);
console.log(session?.estimatedExpiresAt);
console.log(session?.estimatedTtlMs);

This reads the current client-side session maintained by the underlying web SDK.


Cross-Platform Event Naming

With captureErrors on <FlashAnalyticsComponent>, Next.js emits the same event names as all other SDKs:

| Event | Trigger | |---|---| | js_error | Uncaught JS exception (captureErrors) | | unhandled_promise_rejection | Unhandled promise rejection (captureErrors) | | client_error (errorType: "react_render_error") | React component tree crash (<FlashErrorBoundary>) |

The legacy useAutoErrorTracking hook emits client_error (with errorType: "uncaught_exception" or "unhandled_rejection") instead. If you have existing queries filtering on client_error, migrate them to js_error / unhandled_promise_rejection after switching to captureErrors.


Automated Error Tracking

Add captureErrors to <FlashAnalyticsComponent> to automatically capture uncaught JS exceptions and unhandled promise rejections. These are sent as js_error and unhandled_promise_rejection events — the same event names used by all other Flash Analytics SDKs.

For React component tree crashes, wrap your layout with <FlashErrorBoundary>.

App Router (app/layout.tsx):

import { FlashAnalyticsComponent, FlashErrorBoundary } from '@flash-analytics/nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const appId = process.env.NEXT_PUBLIC_FLASH_ANALYTICS_APP_ID!;
  const endpoint = process.env.NEXT_PUBLIC_FLASH_ANALYTICS_ENDPOINT ?? 'https://api.flashanalytics.app';

  return (
    <html lang="en">
      <body>
        {/* captureErrors handles window/promise errors → js_error + unhandled_promise_rejection */}
        <FlashAnalyticsComponent
          appId={appId}
          endpoint={endpoint}
          capturePageViews
          captureErrors
        />
        {/* FlashErrorBoundary catches React render crashes → client_error with errorType: react_render_error */}
        <FlashErrorBoundary
          clientId={appId}
          apiUrl={`${endpoint}/track`}
          fallback={<h1>Something went wrong.</h1>}
        >
          {children}
        </FlashErrorBoundary>
      </body>
    </html>
  );
}

Event names

| Error type | Event emitted | How | |---|---|---| | Uncaught JS exception | js_error | captureErrors on <FlashAnalyticsComponent> | | Unhandled promise rejection | unhandled_promise_rejection | captureErrors on <FlashAnalyticsComponent> | | React render crash | client_error (errorType: "react_render_error") | <FlashErrorBoundary> |

Legacy: useAutoErrorTracking

useAutoErrorTracking is still available but emits client_error (with errorType: "uncaught_exception" / "unhandled_rejection") rather than the cross-platform js_error / unhandled_promise_rejection event names. New apps should use captureErrors instead.