Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Web Vitals Score Monitoring Block for React Aria

Four Core Web Vitals over 28 days as small multiples with good, needs work and poor zones, a release pin and one range cursor that reads LCP, INP, CLS and TTFB for the same day.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Follow the four Core Web Vitals at once with this vitals panel for React with React Aria. It is Vitalane, a vitals tracker, showing 28 typed days to 17 October 2026. Largest Contentful Paint, Interaction to Next Paint, Cumulative Layout Shift and Time to First Byte each get a small chart on a shared hairline: the 75th percentile as a line over three zones in foreground weights (good, needs work, poor) and a pin where release 4.18 shipped. One range under the header moves a cursor across all four charts; every cell reads its value on that day in big figures and in words, and the line under the range lists the four together ("17 Oct: LCP 2.7 s Needs work, INP 173 ms Good, CLS 0.04 Good, TTFB 0.59 s Good."). The header counts how many vitals are good on the last day and names the ones that are not. Guides draw the frame and its bands; the entrance is CSS only. For release reviews, performance budgets and any report where the vitals have to be read together.

FAQ

How do I use my own series?

Each entry of SPECS holds the limits of one vital (good, poor, the chart's max) and the levels that draw its typed series: before and after the release, with a small fixed wobble. Replace pointsOf with your own 28 daily values per vital, rounded the way the cell prints them, and the zones, the words, the cursor and the header sentence follow.

Where do the limits come from?

They are the published Core Web Vitals thresholds at the 75th percentile: LCP good up to 2.5 s and poor over 4 s, INP 200 ms and 500 ms, CLS 0.1 and 0.25, and Time to First Byte 0.8 s and 1.8 s. Each cell prints its own limits under the chart, so the zones are never a guess.

What stays local in the demo?

Everything. The 28 days are typed, nothing is measured or sent, and the cursor only moves what is shown. In your app compute the daily p75 from your field data and pass the four arrays in.

How does the cursor work for keyboard and screen reader users?

It is a native range input with a visible label, one step per day and a spoken value of the date. The reading under it is not announced on every step; when you stop (key up, pointer up or leaving the control) the polite status line at the foot reads the four vitals for that day.

How does it look on a phone?

The four cells stack in one column, each with its value, its 28-day chart at 96 px and its limits. The range stays above them, full width, so the cursor and the values are on the same screen.

Are the charts readable without seeing them?

Every chart is decorative to a screen reader and has a text equivalent: the vital's full name, the value on the first and the last day, and the day of the release. The value at the cursor and its zone are plain text in the cell.