Skip to content

Commit

Permalink
Send web vitals to Vercel analytics
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes Bornö committed Sep 19, 2022
1 parent d41ca43 commit 1b4cb28
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
6 changes: 6 additions & 0 deletions packages/next/client/app-index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import ReactDOMClient from 'react-dom/client'
import React from 'react'
import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-webpack'

import measureWebVitals from './performance-relayer'

/// <reference types="react-dom/experimental" />

// Override chunk URL mapping in the webpack runtime
Expand Down Expand Up @@ -151,6 +153,10 @@ function ServerRoot({ cacheKey }: { cacheKey: string }) {
}

function Root({ children }: React.PropsWithChildren<{}>): React.ReactElement {
React.useEffect(() => {
measureWebVitals()
}, [])

if (process.env.__NEXT_TEST_MODE) {
// eslint-disable-next-line react-hooks/rules-of-hooks
React.useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/next/client/performance-relayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function onReport(metric: Metric): void {
const body: Record<string, string> = {
dsn: process.env.__NEXT_ANALYTICS_ID,
id: metric.id,
page: window.__NEXT_DATA__.page,
page: window.__NEXT_DATA__?.page,
href: initialHref,
event_name: metric.name,
value: metric.value.toString(),
Expand Down
37 changes: 37 additions & 0 deletions test/e2e/app-dir/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ describe('app dir', () => {
'react-dom': 'experimental',
},
skipStart: true,
env: {
VERCEL_ANALYTICS_ID: 'fake-analytics-id',
},
})

if (assetPrefix) {
Expand Down Expand Up @@ -1454,6 +1457,40 @@ describe('app dir', () => {
})
})

// Analytics events are only sent in production
;(isDev ? describe.skip : describe)('Vercel analytics', () => {
it('should send web vitals to Vercel analytics', async () => {
let eventsCount = 0
let countEvents = false
const browser = await webdriver(next.url, '/client-nested', {
beforePageLoad(page) {
page.route(
'https://vitals.vercel-insights.com/v1/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.elementByCss('button').click()

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

describe('known bugs', () => {
it('should not share flight data between requests', async () => {
const fetches = await Promise.all(
Expand Down

0 comments on commit 1b4cb28

Please sign in to comment.