Next.js: [Typescript] missing reportWebVitals type

Created on 28 May 2020  路  2Comments  路  Source: vercel/next.js

Bug report

Describe the bug

I was not able to find the types for reportWebVitals

To Reproduce

Change _app.js to _app.tsx and enable typescript functionality

Expected behavior

reportWebVitals types should be present

System information

  • Version of Next.js: 7.4.4
good first issue story feature request

Most helpful comment

This is no fix, but here's how I did it, until proper types are added:

_app.tsx

/**
 * Global variable meant to keep all metrics together, until there are enough to send them in batch as a single report
 */
const globalWebVitalsMetric: NextWebVitalsMetricsReport = {
  reportId: uuid(),
  metrics: {},
  reportedCount: 0,
};

/**
 * Will be called once for every metric that has to be reported.
 *
 * There are, at minimum, 3 metrics being received (Next.js-hydration, FCP and TTFB)
 * Then, 2 other metrics can be received optionally (FID, LCP)
 *
 * @param metrics
 * @see https://web.dev/vitals/ Essential metrics for a healthy site
 * @see https://nextjs.org/blog/next-9-4#integrated-web-vitals-reporting Initial release notes
 */
export function reportWebVitals(metrics: NextWebVitalsMetrics): void {
  if (process.env.APP_STAGE !== 'production') {
    console.debug(metrics);
  }

  const { name } = metrics;
  const count = globalWebVitalsMetric.reportedCount;
  globalWebVitalsMetric.metrics[name] = metrics;
  const keysLength = Object.keys(globalWebVitalsMetric.metrics).length;

  // Temporise analytics API calls by waiting for at least 5 metrics to be received before sending the first report
  // (because 3 metrics will be received upon initial page load, and then 2 more upon first click)
  // Then, send report every 2 metrics (because each client-side redirection will generate 2 metrics)
  if ((count === 0 && keysLength === 5) || (count > 0 && keysLength === 2)) {
    sendWebVitals(globalWebVitalsMetric);

    // Reset and prepare next metrics to be reported
    globalWebVitalsMetric.metrics = {};
    globalWebVitalsMetric.reportedCount++;
  }
}
import { NextWebVitalsMetrics } from './NextWebVitalsMetrics';

/**
 * Group all vital metrics together, using their own "name" property as key.
 *
 * Meant to help regroup multiple reports together to send them all at once, to reduce API calls.
 *
 * @see https://web.dev/vitals/ Essential metrics for a healthy site
 * @see https://nextjs.org/blog/next-9-4#integrated-web-vitals-reporting
 */
export type NextWebVitalsMetricsReport = {
  reportedCount: number; // Number of times a report has been sent, kinda help to trace how long a same client-side session was
  reportId: string; // ID of the "report", helps grouping reports with different data but same reportId together when analysing data
  metrics: {
    FCP?: NextWebVitalsMetrics; // First contentful paint, triggers on page load
    FID?: NextWebVitalsMetrics; // First input delay, trigger on first end-user interaction (click)
    LCP?: NextWebVitalsMetrics; // Largest contentful paint, triggers on first end-user interaction (sometimes doesn't trigger)
    'Next.js-hydration'?: NextWebVitalsMetrics; // Triggers on page load
    'Next.js-render'?: NextWebVitalsMetrics; // Triggers on client-side redirection (<Link>)
    'Next.js-route-change-to-render'?: NextWebVitalsMetrics; // Triggers on client-side redirection (<Link>)
    TTFB?: NextWebVitalsMetrics; // Time to first byte, triggers on page load
  }
}
/**
 * Web vitals provided to _app.reportWebVitals by Core Web Vitals plugin developed by Google Chrome team.
 *
 * It's the core runtime of what Google LightHouse is build atop.
 *
 * @see https://web.dev/vitals/ Essential metrics for a healthy site
 * @see https://nextjs.org/blog/next-9-4#integrated-web-vitals-reporting
 */
export type NextWebVitalsMetrics = {
  id: string;
  label: string;
  name: string;
  startTime: number;
  value: number;
}

All 2 comments

This is no fix, but here's how I did it, until proper types are added:

_app.tsx

/**
 * Global variable meant to keep all metrics together, until there are enough to send them in batch as a single report
 */
const globalWebVitalsMetric: NextWebVitalsMetricsReport = {
  reportId: uuid(),
  metrics: {},
  reportedCount: 0,
};

/**
 * Will be called once for every metric that has to be reported.
 *
 * There are, at minimum, 3 metrics being received (Next.js-hydration, FCP and TTFB)
 * Then, 2 other metrics can be received optionally (FID, LCP)
 *
 * @param metrics
 * @see https://web.dev/vitals/ Essential metrics for a healthy site
 * @see https://nextjs.org/blog/next-9-4#integrated-web-vitals-reporting Initial release notes
 */
export function reportWebVitals(metrics: NextWebVitalsMetrics): void {
  if (process.env.APP_STAGE !== 'production') {
    console.debug(metrics);
  }

  const { name } = metrics;
  const count = globalWebVitalsMetric.reportedCount;
  globalWebVitalsMetric.metrics[name] = metrics;
  const keysLength = Object.keys(globalWebVitalsMetric.metrics).length;

  // Temporise analytics API calls by waiting for at least 5 metrics to be received before sending the first report
  // (because 3 metrics will be received upon initial page load, and then 2 more upon first click)
  // Then, send report every 2 metrics (because each client-side redirection will generate 2 metrics)
  if ((count === 0 && keysLength === 5) || (count > 0 && keysLength === 2)) {
    sendWebVitals(globalWebVitalsMetric);

    // Reset and prepare next metrics to be reported
    globalWebVitalsMetric.metrics = {};
    globalWebVitalsMetric.reportedCount++;
  }
}
import { NextWebVitalsMetrics } from './NextWebVitalsMetrics';

/**
 * Group all vital metrics together, using their own "name" property as key.
 *
 * Meant to help regroup multiple reports together to send them all at once, to reduce API calls.
 *
 * @see https://web.dev/vitals/ Essential metrics for a healthy site
 * @see https://nextjs.org/blog/next-9-4#integrated-web-vitals-reporting
 */
export type NextWebVitalsMetricsReport = {
  reportedCount: number; // Number of times a report has been sent, kinda help to trace how long a same client-side session was
  reportId: string; // ID of the "report", helps grouping reports with different data but same reportId together when analysing data
  metrics: {
    FCP?: NextWebVitalsMetrics; // First contentful paint, triggers on page load
    FID?: NextWebVitalsMetrics; // First input delay, trigger on first end-user interaction (click)
    LCP?: NextWebVitalsMetrics; // Largest contentful paint, triggers on first end-user interaction (sometimes doesn't trigger)
    'Next.js-hydration'?: NextWebVitalsMetrics; // Triggers on page load
    'Next.js-render'?: NextWebVitalsMetrics; // Triggers on client-side redirection (<Link>)
    'Next.js-route-change-to-render'?: NextWebVitalsMetrics; // Triggers on client-side redirection (<Link>)
    TTFB?: NextWebVitalsMetrics; // Time to first byte, triggers on page load
  }
}
/**
 * Web vitals provided to _app.reportWebVitals by Core Web Vitals plugin developed by Google Chrome team.
 *
 * It's the core runtime of what Google LightHouse is build atop.
 *
 * @see https://web.dev/vitals/ Essential metrics for a healthy site
 * @see https://nextjs.org/blog/next-9-4#integrated-web-vitals-reporting
 */
export type NextWebVitalsMetrics = {
  id: string;
  label: string;
  name: string;
  startTime: number;
  value: number;
}

I'll take this up

Was this page helpful?
0 / 5 - 0 ratings

Related issues

olifante picture olifante  路  3Comments

YarivGilad picture YarivGilad  路  3Comments

formula349 picture formula349  路  3Comments

wagerfield picture wagerfield  路  3Comments

rauchg picture rauchg  路  3Comments