Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add useReportWebVitals that makes use of web-vitals package (#47319)
### 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
Showing
8 changed files
with
127 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './dist/client/web-vitals' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('./dist/client/web-vitals') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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} | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Reporter from './reporter' | ||
|
||
export default function component() { | ||
return ( | ||
<> | ||
<h1>Test</h1> | ||
<Reporter /> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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/) | ||
}) | ||
}) |