Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Rate Limit Error Block for React

A full-screen 429 for an API key over its limit: a 10 by 10 grid of the last 60 seconds of requests, the Retry-After header worked out from the oldest, and a demo clock that empties the oldest cells so Retry works.

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

Show a developer why they were stopped and exactly when to come back, with this rate limit page for React with Base UI. It's the 429 screen of Mapwren, a geocoding API: a whole screen with the page's rails and one band across it, split in two. At the start, the code as display text, the heading, the limit and what the key has used, the response header it would get (Retry-After: 38, worked out from the oldest request) and the actions: a Shine Button, Retry, and a demo control, Let 10 seconds pass. At the end, framed by Guides, the sliding window as a 10 by 10 grid: one cell for each of the last 100 requests, each with a typed age and drawn lighter as it ages. Letting time pass moves a typed clock, the oldest cells empty first, and Retry takes the first free one. It's built from Button, Shine Button and Guides, with a CSS entrance only. For any API with a per-minute limit.

FAQ

What is a sliding window, and why is it a grid?

A request counts against the limit for 60 seconds after it was sent, so slots free one at a time as the oldest requests age out, not all at once at the top of the minute. The grid shows that: 100 cells, one per request, ordered oldest first, and the cells that leave the window are the first ones. Tones show the age: solid under 20 seconds, lighter at 20 to 40 and lighter again at 40 to 60.

Why is there no timer?

Because nothing in a page like this should tick on its own. The clock is a number the visitor moves: Let 10 seconds pass adds 10 to it, and everything else (the ages, the free count, Retry-After) is derived from the request times and that number. Start over puts it back at the moment of the error. A real page would show the header your limiter sent, and could count down from it.

How is Retry-After worked out, and what does Retry do?

Retry-After is the 60 seconds minus the age of the oldest request still in the window, 38 here because the oldest was sent 22 seconds before the page loaded. While no cell is free, Retry says "Still over the limit. Retry in 38 seconds of demo time. Nothing was sent." Once one is free, it takes the first free cell as a new request and says "Accepted in this demo: 13 remain." Nothing is sent anywhere.

How do I wire it to a real limiter?

Return a 429 from your server with a Retry-After header in seconds, and give the page the request times from your limiter (a sorted set of timestamps per key works for a sliding window). Replace the typed COUNTS with them, keep LIMIT and WINDOW, and the header, counts and grid follow.

How do screen readers read the grid?

The cells are a drawing, hidden from screen readers; the same facts are in the text: the limit, "100 of 100" in the window, the header, the free count in the status line after each action and a caption for the figure. In a right-to-left layout the grid keeps its order, because it is a time order and not text.

Does this return a 429 status?

No: a component can't. Send a real 429 with Retry-After from your server, so well-behaved clients back off, and don't return a 200 with an error drawn on it.

  • Pro

    Rate Limiting Settings

    API and webhooks

    A rate limit you can try: a framed strip replays one client's 24 requests over 10 seconds against the chosen algorithm, limit, window and burst, marking each request allowed or rejected and counting both.

  • Pro

    Rate Limit Dialog

    Status and errors

    An API console with its 429 notice shown open: a dialog with the quota used, the plan's limit, a clock to the reset and a Countdown Button that turns into Retry request when the wait ends.

  • Pro

    A panel for a vault that is over its storage: one bar on a fixed axis with the trash and a hatched overshoot, a table whose states are worked out from the numbers, and a Shine Button that empties the trash and redraws everything.

  • Pro

    A matrix of API limits with the plans across and a number field in every cell, a daily capacity worked out under each plan and a guard that stops a higher plan from allowing less than the plan before it.

  • Pro

    Request Timeout Error

    Server and outages

    A full-height 408 page for a report generator: a request waterfall on a fixed time axis with a cut line at the wait you choose, a verdict that says whether the answer would have arrived, and a Retry that names the wait.

  • Pro

    API Uptime Strips Error

    Server and outages

    A full-screen outage page for an API host: the display 503, a notify-me form that saves in the page, and four APIs as rows of thirty day-cells with a shape and a word for today and an uptime counted from the minutes.