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

@signalor/nextjs

v0.2.0

Published

Signalor SDK for Next.js — auto-injects schema markup, serves llms.txt + sitemap, and reports deploys to Signalor for GEO scoring.

Readme

@signalor/nextjs

Signalor SDK for Next.js. Auto-injects schema markup, serves /llms.txt and /sitemap.xml, and reports each deploy to Signalor so your GEO score stays current — usually four lines of code per app.

Install

pnpm add @signalor/nextjs

Then set your API key (mint one at signalor.ai → Settings → Developers):

# .env
SIGNALOR_API_KEY=sk_live_...

That's it. Now wire up whichever pieces you want.

Middleware — AI-crawler detection (edge runtime)

// On Next.js 16+: src/proxy.ts (the new name for middleware)
// On Next.js 14/15: src/middleware.ts
import { signalorMiddleware } from "@signalor/nextjs/middleware";

export default signalorMiddleware();

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};

Stamps x-signalor-ai-crawler: <bot-name> on responses to known AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Bytespider, etc.). Pass options to record analytics or swap behaviour:

export default signalorMiddleware({
  onDetected: (info) => analytics.track("ai_crawler", info),
  headerName: "x-ai-bot", // or `false` to disable
});

Next.js 16 note: the middleware file convention was renamed to proxy. The CLI auto-detects your version and writes the right filename. If you're hand-wiring on 16+, use src/proxy.ts.

The import + export default signalorMiddleware() form is intentional: signalorMiddleware is a factory that returns the actual handler. Re-export shortcuts like export { signalorMiddleware as default } confuse Next.js 16's static analyzer — use the explicit form above.

Schema markup — <SignalorSchema />

// app/layout.tsx
import { SignalorSchema } from "@signalor/nextjs";

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <SignalorSchema />
      </head>
      <body>{children}</body>
    </html>
  );
}

Server component. Fetches your org's Organization + WebSite defaults from Signalor (cached 24h) and emits a single <script type="application/ld+json">. Pass additional to merge per-page schema:

<SignalorSchema additional={[{ "@type": "Article", headline: post.title, datePublished: post.date }]} />

/llms.txt route

// app/llms.txt/route.ts
export { GET } from "@signalor/nextjs/llms-txt";

Renders an llms.txt populated from your Signalor org profile. Cached for 1 hour with Cache-Control headers. Fails open with a minimal stub if Signalor is unreachable, so the route never 5xx's.

Sitemap

// app/sitemap.ts
export { default } from "@signalor/nextjs/sitemap";

Reads routes from SIGNALOR_SITEMAP_ROUTES env (comma-separated paths) and prefixes them with your org's primary URL. To compose with your own route discovery:

import { signalorSitemap } from "@signalor/nextjs/sitemap";

export default async function sitemap() {
  return signalorSitemap({ routes: await loadRoutesFromCms() });
}

Snapshot route — score sites behind Cloudflare / Turnstile

// app/api/signalor/snapshot/route.ts
export { GET } from "@signalor/nextjs/snapshot";

If your site sits behind a Cloudflare managed challenge / Turnstile (or any bot protection), Signalor's crawler is served a "Just a moment…" interstitial instead of your content, and your GEO score collapses. This route lets the analyzer read your site's own server-rendered HTML — fetched from your deployment origin (the *.vercel.app host, which is not behind your Cloudflare) — so scoring works regardless of your edge protection.

Every request is HMAC-signed with your API key and time-bounded, so the route never exposes your content publicly (unsigned/stale requests get a 401). The analyzer pulls / plus the routes in SIGNALOR_SITEMAP_ROUTES.

On Vercel it works with zero extra config (uses VERCEL_URL). On other hosts, set SIGNALOR_ORIGIN to an origin the route can self-fetch that isn't behind your CDN.

Deploy notifier

// package.json
{
  "scripts": {
    "postbuild": "signalor-deploy"
  }
}

Runs after every build. Auto-detects the deploy context — commit, environment, URL — from Vercel (VERCEL_*), Netlify (NETLIFY, CONTEXT, URL), or your own env vars (SIGNALOR_DEPLOY_URL, SIGNALOR_DEPLOY_COMMIT, SIGNALOR_DEPLOY_ENV). Reports to Signalor, which kicks off a fresh GEO analysis and surfaces it in the dashboard's Deployments tab.

The script never fails your build. Missing key → warns, exits 0. Network error → warns, exits 0.

Configuration

| Env var | Default | Used by | | ----------------------------- | --------------------------- | ---------------------------------------- | | SIGNALOR_API_KEY | (required) | every server-side primitive | | SIGNALOR_API_BASE | https://api.signalor.ai | every server-side primitive | | SIGNALOR_APP_BASE | https://signalor.ai | dashboard links | | SIGNALOR_SITEMAP_ROUTES | / | sitemap + snapshot routes (comma-separated) | | SIGNALOR_ORIGIN | https://$VERCEL_URL | snapshot route self-fetch origin | | SIGNALOR_DEPLOY_URL | (detect) | signalor-deploy on self-hosted | | SIGNALOR_DEPLOY_COMMIT | (detect) | signalor-deploy on self-hosted | | SIGNALOR_DEPLOY_ENV | production | signalor-deploy on self-hosted | | SIGNALOR_DEPLOY_HOST | self-hosted | signalor-deploy on self-hosted |

Runtime

  • Edge-safe: @signalor/nextjs/middleware runs in the edge runtime. No Node-only APIs.
  • Server components: <SignalorSchema />, the llms.txt route, the sitemap, and the snapshot route run in the Node runtime — they use native fetch, which Next.js caches automatically.
  • Zero runtime deps: only peer-deps next and react.

Roadmap

  • signalor-cli init — automated wire-up via npx.
  • Vercel marketplace listing — one-click install + provisioned env vars.
  • Per-route schema overrides via Next.js metadata API.
  • Bulk metadata push from the build step (currently the SDK uses the /metadata/bulk endpoint but doesn't auto-collect — coming in 0.2).

License

MIT