Vercel Analytics supports Next.js, Nuxt.js, and Gatsby with zero configuration through build plugins. You can use Vercel Analytics with any frontend framework or project through the Vercel Analytics API as shown below.
post /v1/vitals
Send web vitals data to the Vercel Analytics API.
Body Parameters
Body Parameter | Description |
---|---|
dsn | string Unique identifier for the project, exposed during the build as an environment variable VERCEL_ANALYTICS_ID |
event_name | string Name of the vital to track, provided by the web-vitals package |
href | string The full URL for the deployed application |
id | string Unique identifier for the vital to track, provided by the web-vitals package |
page | string The file name a framework could translate into a resolved URL path |
speed | string Connection information from the visitor device, which can be provided by the web Navigator API |
value | string Value of the vital to track, provided by the web-vitals package |
Response
200 OK
Response Codes
Code | Description |
---|---|
200 | Successful response. |
400 | One of the body values is invalid or missing. |
403 | You do not have permission to access this resource. |
To use the Analytics API, you'll need to retrieve the analytics ID for your Vercel project. This value is exposed during the build and can be accessed by process.env.VERCEL_ANALYTICS_ID
inside Node.js.
Inside your framework or Node.js script, you can then use this value in the body
of your request to the Vercel Analytics API.
vc pull
does not pull VERCEL_ANALYTICS_ID
as the Vercel Analytics ID environment variable is inlined during the build process. It is not part of your project Environment Variables, which can be pulled locally using the CLI.You can view an example of the following code implemented inside our Create React App and SvelteKit starters.
import { getCLS, getFCP, getFID, getLCP, getTTFB } from 'web-vitals';
const vitalsUrl = 'https://vitals.vercel-analytics.com/v1/vitals';
function getConnectionSpeed() {
return 'connection' in navigator &&
navigator['connection'] &&
'effectiveType' in navigator['connection']
? navigator['connection']['effectiveType']
: '';
}
function sendToAnalytics(metric, options) {
const page = Object.entries(options.params).reduce(
(acc, [key, value]) => acc.replace(value, `[${key}]`),
options.path,
);
const body = {
dsn: options.analyticsId, // qPgJqYH9LQX5o31Ormk8iWhCxZO
id: metric.id, // v2-1653884975443-1839479248192
page, // /blog/[slug]
href: location.href, // https://my-app.vercel.app/blog/my-test
event_name: metric.name, // TTFB
value: metric.value.toString(), // 60.20000000298023
speed: getConnectionSpeed(), // 4g
};
if (options.debug) {
console.log('[Analytics]', metric.name, JSON.stringify(body, null, 2));
}
const blob = new Blob([new URLSearchParams(body).toString()], {
// This content type is necessary for `sendBeacon`
type: 'application/x-www-form-urlencoded',
});
if (navigator.sendBeacon) {
navigator.sendBeacon(vitalsUrl, blob);
} else
fetch(vitalsUrl, {
body: blob,
method: 'POST',
credentials: 'omit',
keepalive: true,
});
}
export function webVitals(options) {
try {
getFID((metric) => sendToAnalytics(metric, options));
getTTFB((metric) => sendToAnalytics(metric, options));
getLCP((metric) => sendToAnalytics(metric, options));
getCLS((metric) => sendToAnalytics(metric, options));
getFCP((metric) => sendToAnalytics(metric, options));
} catch (err) {
console.error('[Analytics]', err);
}
}