Analytics
Next.js has built-in support for measuring and reporting performance metrics. You can either use the useReportWebVitals hook to manage reporting yourself, or alternatively, Vercel provides a managed service to automatically collect and visualize metrics for you.
Build Your Own
1'use client'23import { useReportWebVitals } from 'next/web-vitals'45export function WebVitals() {6useReportWebVitals(metric => {7console.log(metric)8})9}
1import { WebVitals } from './_components/web-vitals'23export default function Layout({ children }) {4return (5<html>6<body>7<WebVitals />8{children}9</body>10</html>11)12}
Since the
useReportWebVitalshook requires the"use client"directive, the most performant approach is to create a separate component that the root layout imports. This confines the client boundary exclusively to theWebVitalscomponent.
View the API Reference for more information.
Web Vitals
Web Vitals are a set of useful metrics that aim to capture the user experience of a web page. The following web vitals are all included:
- Time to First Byte (TTFB)
- First Contentful Paint (FCP)
- Largest Contentful Paint (LCP)
- First Input Delay (FID)
- Cumulative Layout Shift (CLS)
- Interaction to Next Paint (INP)
You can handle all the results of these metrics using the name property.
1'use client'23import { useReportWebVitals } from 'next/web-vitals'45export function WebVitals() {6useReportWebVitals(metric => {7switch (metric.name) {8case 'FCP': {9// handle FCP results10}11case 'LCP': {12// handle LCP results13}14// ...15}16})17}
Sending results to external systems
You can send results to any endpoint to measure and track real user performance on your site. For example:
1useReportWebVitals(metric => {2const body = JSON.stringify(metric)3const url = 'https://example.com/analytics'45// Use `navigator.sendBeacon()` if available, falling back to `fetch()`.6if (navigator.sendBeacon) {7navigator.sendBeacon(url, body)8} else {9fetch(url, { body, method: 'POST', keepalive: true })10}11})
Good to know: If you use Google Analytics, using the
idvalue can allow you to construct metric distributions manually (to calculate percentiles, etc.)
1useReportWebVitals(metric => {2// Use `window.gtag` if you initialized Google Analytics as this example:3// https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/_app.js4window.gtag('event', metric.name, {5value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value), // values must be integers6event_label: metric.id, // id unique to current page load7non_interaction: true, // avoids affecting bounce rate.8});9}Read more about sending results to Google Analytics.