Next.js
适用于@openrum/browser 0.1.2
Next.js 会在服务端渲染,而 @openrum/browser 是浏览器 SDK,所以真正需要决定的只有一件事:
init() 必须在浏览器里执行,且只在浏览器里执行。
"use client" 本身不是屏障。Client Component 在渲染期间仍会在服务端被求值一次,因此写在其中的
模块级 init() 会在 Node 下执行;又因为 activeClient 是模块级单例,那个已经失效的 client 会被
服务端后续处理的每一个请求复用。请改为在 effect 里初始化,它只会在浏览器中执行。
App Router
Section titled “App Router”-
写一个只负责初始化的 Client Component。
app/monitoring.tsx "use client";import { init } from "@openrum/browser";import { useEffect } from "react";export function Monitoring() {useEffect(() => {init({dsn: process.env.NEXT_PUBLIC_OPENRUM_DSN!,environment: process.env.NODE_ENV,release: process.env.NEXT_PUBLIC_APP_RELEASE,});}, []);return null;}已有 client 在运行时
init()会直接返回它,因此开发环境下 Strict Mode 触发两次 effect,也 不会产生两个 client 或两个 Session。 -
在根 layout 里渲染一次。
app/layout.tsx import { Monitoring } from "./monitoring";export default function RootLayout({ children }: { children: React.ReactNode }) {return (<html lang="zh-CN"><body><Monitoring />{children}</body></html>);} -
用
NEXT_PUBLIC_前缀暴露 DSN。它包含浏览器公开的只写凭证,需要进入浏览器 bundle,而这正是 前缀的作用。
Pages Router
Section titled “Pages Router”同样的调用,放在 _app 里:
import { init } from "@openrum/browser";import type { AppProps } from "next/app";import { useEffect } from "react";
export default function App({ Component, pageProps }: AppProps) { useEffect(() => { init({ dsn: process.env.NEXT_PUBLIC_OPENRUM_DSN!, environment: process.env.NODE_ENV, release: process.env.NEXT_PUBLIC_APP_RELEASE, }); }, []);
return <Component {...pageProps} />;}两种 Router 都通过 history.pushState 改变 URL,因此客户端导航无需路由钩子就会产生 Page View。
记录下来的 Route 是解析后的 pathname,也就是说 app/orders/[id] 这样的动态段会被存成
/orders/8fc1,而不是 /orders/[id]。这对 Analysis 的影响见
路由模式。
不在覆盖范围内
Section titled “不在覆盖范围内”| 关注点 | 状态 |
|---|---|
| 服务端渲染期间抛出的错误 | 不采集。SDK 只观测浏览器,这些错误留在 Next.js 的服务端日志里。 |
| Route Handler 与 Server Action | 不直接采集。它们的失败会以浏览器侧失败的 fetch 或 XHR Request 呈现。 |
| Middleware 与 Edge runtime | 不支持。那里既没有 window 也没有localStorage。 |
| Source Map | 构建后按 Release 上传,见 Source Map。 |
Release Alpha · commit local