Skip to content

Commit

Permalink
add useReportWebVitals that makes use of web-vitals package (#47319)
Browse files Browse the repository at this point in the history
### What?
introduce a new hook `useReportWebVitals` that would register a function to handle web-vitals metrics. 

### Why?
next.js users who use [Axiom](https://axiom.co) has been [asking](axiomhq/next-axiom#109) for this feature for nextjs 13, as it was working for nextjs 12.
  • Loading branch information
schehata committed Mar 24, 2023
1 parent be14eb1 commit b39a03f
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/next/package.json
Expand Up @@ -57,7 +57,9 @@
"navigation.d.ts",
"headers.js",
"headers.d.ts",
"navigation-types"
"navigation-types",
"web-vitals.js",
"web-vitals.d.ts"
],
"bin": {
"next": "./dist/bin/next"
Expand Down
23 changes: 23 additions & 0 deletions packages/next/src/client/web-vitals.ts
@@ -0,0 +1,23 @@
import { useEffect } from 'react'
import {
onLCP,
onFID,
onCLS,
onINP,
onFCP,
onTTFB,
Metric,
} from 'next/dist/compiled/web-vitals'

export function useReportWebVitals(
reportWebVitalsFn: (metric: Metric) => void
) {
useEffect(() => {
onCLS(reportWebVitalsFn)
onFID(reportWebVitalsFn)
onLCP(reportWebVitalsFn)
onINP(reportWebVitalsFn)
onFCP(reportWebVitalsFn)
onTTFB(reportWebVitalsFn)
}, [reportWebVitalsFn])
}
1 change: 1 addition & 0 deletions packages/next/web-vitals.d.ts
@@ -0,0 +1 @@
export * from './dist/client/web-vitals'
1 change: 1 addition & 0 deletions packages/next/web-vitals.js
@@ -0,0 +1 @@
module.exports = require('./dist/client/web-vitals')
19 changes: 19 additions & 0 deletions test/e2e/app-dir/app/app/report-web-vitals/layout.js
@@ -0,0 +1,19 @@
'use client'

import { useState, useEffect } from 'react'

export default function ClientNestedLayout({ children }) {
const [count, setCount] = useState(0)
useEffect(() => {
setCount(1)
}, [])
return (
<>
<h1>Client Nested. Count: {count}</h1>
<button id="btn" onClick={() => setCount(count + 1)}>
{count}
</button>
{children}
</>
)
}
10 changes: 10 additions & 0 deletions test/e2e/app-dir/app/app/report-web-vitals/page.js
@@ -0,0 +1,10 @@
import Reporter from './reporter'

export default function component() {
return (
<>
<h1>Test</h1>
<Reporter />
</>
)
}
17 changes: 17 additions & 0 deletions test/e2e/app-dir/app/app/report-web-vitals/reporter.js
@@ -0,0 +1,17 @@
'use client'
import { useReportWebVitals } from 'next/web-vitals'

const report = (metric) => {
const blob = new Blob([new URLSearchParams(metric).toString()])
const vitalsUrl = 'https://example.vercel.sh/vitals'
fetch(vitalsUrl, {
body: blob,
method: 'POST',
credentials: 'omit',
keepalive: true,
})
}

export default function Reporter() {
useReportWebVitals(report)
}
53 changes: 53 additions & 0 deletions test/e2e/app-dir/app/useReportWebVitals.test.ts
@@ -0,0 +1,53 @@
import { createNext } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import { check } from 'next-test-utils'

describe('useReportWebVitals hook', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: __dirname,
dependencies: {
swr: '2.0.0-rc.0',
react: 'latest',
'react-dom': 'latest',
sass: 'latest',
},
skipStart: true,
env: {},
})

await next.start()
})
afterAll(() => next.destroy())

// Analytics events are only sent in production
it('should send web-vitals to vercel-insights', async () => {
let countEvents = false
let eventsCount = 0
const browser = await next.browser('/report-web-vitals', {
beforePageLoad: (page) => {
page.route('https://example.vercel.sh/vitals', (route) => {
if (countEvents) {
eventsCount += 1
}

route.fulfill()
})
},
})

// Start counting analytics events
countEvents = true

// Refresh will trigger CLS and LCP. When page loads FCP and TTFB will trigger:
await browser.refresh()

// After interaction LCP and FID will trigger
await browser.elementById('btn').click()

// Make sure all registered events in performance-relayer has fired
await check(() => eventsCount, /6/)
})
})

0 comments on commit b39a03f

Please sign in to comment.