Skip to content

Duplicate Core Web Vital metrics on soft navigations when using useReportWebVitals in Pages router #79800

@glifchits

Description

@glifchits

Link to the code that reproduces this issue

https://github.com/glifchits/next-cwv-pages-router-repro

To Reproduce

  1. Build a Next.js pages router application and implement useReportWebVitals following instructions in the documentation (code in repro repository)
  2. Observe the emitted CWV events, paying attention to the events emitted after a soft navigation ("client-side navigation" as implemented by next/link)

Current vs. Expected behavior

Current: after a pages router soft navigation, useReportWebVitals emits duplicate metrics such as LCP, TTFB, etc.

Expected: soft navigations do not cause metrics to be emitted by default. Particularly not with values that duplicate the first emitted metric values.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 22.1.0
  npm: 10.7.0
  Yarn: 1.22.22
  pnpm: 10.2.0
Relevant Packages:
  next: 15.3.2 // Latest available version is detected (15.3.2).
  eslint-config-next: 15.3.2
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.8.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Instrumentation

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local), Other (Deployed)

Additional context

CWV on soft navigations are experimental and there's a case to be made for opting-in to the experimental measurement, however the duplicate measurements seem like the bigger issue, as this could bias production RUM measurements.

I have tested this in app router, and following the documentation (adding a client component to the root layout), it seems to be working aligned with my expectation. So this seems like a bug with how the hook behaves in pages router.

In our pages router implementation of CWV tracking, we add a function that's executed in the client runtime on the global scope of _app.tsx and this seems to produce the expected behaviour I described above. So long as my understanding of the CWV reporting behaviour is accurate, I'm not sure if a React hook is the correct API for pages router, and perhaps the docs should recommend a different approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    InstrumentationRelated to Next.js Instrumentation.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions