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

@yunlideyang/analytics-sdk

v0.1.4

Published

Lightweight, framework-agnostic browser analytics SDK for personal-website-analytics.

Readme

@yunlideyang/analytics-sdk

浏览器端 Analytics 采集 SDK。用于在前端应用中上报页面访问、自定义事件和 Core Web Vitals,并发送到配置的 HTTP 接收地址。

用途

  • 采集浏览器页面访问和自定义事件。
  • 自动补充并清洗页面上下文:路径、路由信息、UTM、语言、时区、设备类型、屏幕尺寸和视口尺寸。
  • 基于 web-vitals 包采集 LCP、INP、CLS。
  • 处理匿名标识、内存队列、失败重试和页面退出时的 Beacon 发送。

默认行为

  • 无框架绑定,不内置 React/Vue/Svelte 适配层。
  • 默认遵守 Do Not Track。
  • 默认清洗 query value 和 URL hash。
  • 页面访问自动上报和路由变化自动上报都需要显式开启。

取舍

  • 这是浏览器采集 SDK,不是看板或数据存储。
  • Core Web Vitals 能力取决于浏览器支持和底层 web-vitals 实现。
  • 通用 SDK 无法自动推断框架路由 pattern;需要路由维度统计时由应用传入路由元数据。
  • 浏览器端配置都是公开信息,不要在 SDK 配置中放入任何秘密。

安装

npm install @yunlideyang/analytics-sdk

快速开始

import { initAnalytics } from '@yunlideyang/analytics-sdk';

const analytics = initAnalytics({
  siteId: 'personal-website',
  endpoint: '/api/analytics',
});

analytics.trackPageView();
analytics.track('resume_download', {
  targetId: 'resume',
});

大部分配置都有安全默认值。路由自动采集、保留 query value、Web Vitals 都按需再加。

endpoint 是基地址,SDK 会追加:

POST {endpoint}/visits
POST {endpoint}/events
POST {endpoint}/web-vitals

传 /api/analytics,不要传 /api/analytics/events。

配置

| 配置 | 默认值 | 说明 | | --- | --- | --- | | siteId | 必填 | 统计接收地址接受的站点 ID。 | | endpoint | 必填 | Analytics 接收基地址,不能包含 query/hash。 | | autoTrackPageView | false | 初始化后发送一次页面访问。 | | autoTrackRouteChanges | false | 监听 History API pathname 变化。HashRouter 不支持。 | | sanitizeQueryValues | true | 清洗 visit.path 的 query value;接收端也需允许 query value 才会保存。hash 始终丢弃。 | | getPageContext | 未设置 | 补充 routePattern、routeName、title、path 或白名单属性,适合 React Router。 | | debug | false | 输出传输警告。 | | respectDoNotTrack | true | 浏览器开启 DNT 时停止采集。 | | requestTimeoutMs | 5000 | fetch 超时,范围 1-120000。 | | webVitals | 未启用 | 启用 LCP、INP、CLS 采集。 | | webVitals.writeKey | 启用时必填 | Web Vitals 的浏览器公开写入 key;从项目配置读取,不要硬编码示例值。 | | webVitals.releaseVersion | "" | 通常不用填;需要按发布版本对比性能时,传项目已有版本号。 | | webVitals.routeName | "" | 首次文档导航的路由名。 | | webVitals.sendDelayMs | 3000 | Web Vitals 发送等待时间,范围 0-120000。 | | webVitals.reportSoftNavigations | false | 浏览器支持时启用原生 SPA 软导航样本。 |

页面访问

analytics.trackPageView({
  path: '/blog/hello',
  routeName: 'blog-detail',
  routePattern: '/blog/:slug',
  title: document.title,
});

每次页面访问会发送:

  • 一条 visit 到 {endpoint}/visits
  • 一条 page_view event 到 {endpoint}/events

page_view 自动包含白名单上下文:fullPath、previousPath、UTM、landing UTM、语言、时区、设备、屏幕和视口。

Query 口径:

  • 默认只保留 path 和 query key
  • sanitizeQueryValues: false 时 SDK 可在 visit.path 发送 query value
  • 接收端也必须允许 query value
  • event path 和路径类 event properties 仍清洗

路由采集

History 路由:

const analytics = initAnalytics({
  siteId: 'personal-website',
  endpoint: '/api/analytics',
  autoTrackPageView: true,
  autoTrackRouteChanges: true,
  getPageContext: () => ({
    routePattern: currentRoutePattern,
    routeName: currentRouteName,
  }),
});

SDK 监听 pushState、replaceState 和前进/后退,只在 pathname 变化时上报。query-only、hash-only 不产生页面访问。框架路由元数据通过 getPageContext 传入,例如 React Router 的 route pattern。

手动路由:

router.afterEach((to) => {
  analytics.trackPageView({
    path: to.path,
    routeName: String(to.name ?? ''),
    routePattern: String(to.matched?.at(-1)?.path ?? ''),
    title: document.title,
  });
});

同一次导航只用自动或手动其中一种方式。

事件

analytics.track('article_share', {
  articleId: 'article-123',
  targetType: 'social-platform',
  targetId: 'wechat',
});

事件名必须以字母开头,可包含字母、数字、下划线、冒号和连字符,最长 64。

常用白名单属性:

  • 页面:title、routeName、routePattern、fullPath、previousPath、entryPath
  • 来源:utmSource、utmMedium、utmCampaign、landingUtmSource、landingUtmMedium、landingUtmCampaign
  • 设备:deviceType、language、timezone、screenWidth、screenHeight、viewportWidth、viewportHeight
  • 业务:targetType、targetId、articleId、conversionType、conversionTarget
  • 性能/错误:loadTimeMs、lcpMs、inpMs、cls、durationMs、errorType、errorCode、apiPath

不要发送密码、Token、Cookie、表单值、邮箱、手机号或其他个人数据。

Web Vitals

配置 webVitals 后,SDK 使用 web-vitals v6 采集 LCP、INP、CLS。

const analytics = initAnalytics({
  siteId: 'personal-website',
  endpoint: '/api/analytics',
  webVitals: {
    writeKey: import.meta.env.VITE_ANALYTICS_WEB_VITALS_WRITE_KEY,
  },
});
  • webVitals.sendDelayMs 后发送最新快照。
  • 晚到的真实 LCP 会继续发送。
  • 无交互页面不会伪造 INP: 0。
  • 页面隐藏/离开时尽量使用 Beacon。
  • 软导航样本需要浏览器支持,并设置 webVitals.reportSoftNavigations: true。

生命周期

await analytics.flush();
analytics.destroy();

flush() 发送队列。destroy() 移除监听、取消定时器,并停止该客户端继续采集。

匿名标识按站点隔离,优先存入 localStorage/sessionStorage。发送失败不会影响页面业务。