Integrate Sentry's Web Vitals into Slack.
# FrontendIntroduction
Web Vitals is an initiative proposed by Google that aims to provide various metrics to quantify the performance of a website. Previously, there was a video on the Google Chrome Developer channel introducing Core Web Vitals in Taiwanese, which includes some very interesting examples that I recommend checking out ↓
Nowadays, many websites are implementing processes to measure Web Vitals, identifying areas for improvement through quantifiable indicators. There are quite a few tools available to help developers measure Web Vitals, such as:
- Lighthouse
- PageSpeed Insights
- CrUX
- Search Console
Sentry’s Web Vitals Statistics Feature
However, what fewer people know is that Sentry also launched a Web Vitals statistics feature earlier1, which can track various metrics like LCP, FP, and CLS. This allows developers to view related charts in the backend, even labeling the averages, which is quite thoughtful.

Nonetheless, it seems that Sentry only retains data for 30 days, and it does not support comparison features—for instance, comparing last week’s metrics with this week’s metrics. The charts can only be viewed on Sentry, creating a switching cost for other teams. As developers, it’s natural to want to automate the entire process.
Upon further investigation, I found that although Sentry offers API integration (if you have a token), it seems there is no specific API documentation for Web Vitals. However, out of curiosity, I opened the console and noticed that the charts are generated using an API, and after copying the API endpoint and parameters, I successfully called it using CURL! It appears that it just wasn’t documented.

There are two main APIs: * (Note that since there is no documentation, parameters or paths may change) *
/events-measurements-histogram/?.../eventsv2
Automation Process Design
Now that we have the data, we can integrate it into Slack for regular tracking, making it easy to share with others in different teams. For more detailed information, one can refer back to the Sentry dashboard. The entire process is as follows:

By using a cron job to call the API (or writing it as serverless), we can obtain Sentry’s data, upload it, and generate reports.
One crucial point to note is the presence of + in the query parameters; directly sending it to encodeURIComponent or using URLSearchParams will convert it to %2B, resulting in an error from Sentry. Therefore, it’s essential to either extract the + or find a way to prevent it from being encoded.
For example, the API’s query parameters might look like this: field=percentile(measurements.fp%2C+0.75)&field=percentile(measurements.fcp%2C+0.75)&.... You can define the data you want to return in a function-like manner, such as percentile(measurements.fp,+0.75), which returns the 75th percentile of FP data (measured in milliseconds). Notice that while , is encoded as %2C, the + remains unencoded. If there are errors when creating the query parameters, this is a good area to investigate.
The returned data structure will look like this:
{
"path": "/my-page",
"data": [
{
"count": 10,
"bin": 2000
},
...
]
}
Next, we generate a .json file and upload it to S3, or any other storage solution. This way, we can compare it with yesterday’s data (or earlier data) and generate a report sent to Slack:

Additionally, if you want to generate charts, you can use chart.js and chartjs-node-canvas in Node.js to implement this. This allows you to create charts without needing a browser (canvas). Just be aware that if the corresponding fonts are not installed on the server, it may lead to formatting issues or font mismatches.

Regarding cron job selection, there are many mature solutions available now, and even hardcoding a server into crontab is an option. However, here we utilized the cron job feature from Drone CI to implement this. The main reason is that the configuration file for Drone is very convenient to write, and our company has a dedicated Drone CI server, plus we cannot use external services casually. Therefore, integrating with Drone CI was the simplest way to make everything easy to set up.
However, for some reason, every time the cron event is triggered, other pipelines also get triggered. So later, we modified the .yaml to call the API by opening an additional branch:
steps:
- name: upload and report
image: byrnedo/alpine-curl
commands:
- curl -X POST YOUR_SERVER_ENDPOINT
With that, the entire automation implementation is complete. Now we can see reports sent to Slack daily, making it easier for developers to observe changes and receive feedback.
Footnotes
Related Posts
- CSS field-sizing — Auto-Resize Form Elements with One Line of CSSMaking a textarea auto-resize used to require JavaScript to watch scrollHeight. CSS field-sizing: content replaces all of that in one line, supporting textarea, input, and select.
- Make Your Hyperlink Underlines Look Better: text-underline-offsetBy default, underlines sit very close to the text, and some designers dislike this style. Personally, I don’t think it looks very good either.
- Why Web Design Shouldn’t Chase Pixel PerfectOnly pay attention to Pixel Perfect when it really matters; otherwise, it often leads to a lose-lose situation.
- Let’s Write Colors with CSS HSL! (And a Better Way)In web development, the traditional HEX and RGB color notations are widely used, but they are not very readable or intuitive, and their capabilities are limited in wider color spaces such as P3. HSL (Hue, Saturation, Lightness) provides a more intuitive way to define colors, making it easier for developers to understand and adjust them. By describing colors through the three dimensions of hue, saturation, and lightness, HSL makes color adjustment more human-friendly. In design systems in particular, HSL can better represent lightness variations in a color palette.