Enforcing quotas in React without scattering if-statements
Gate features on remaining quota with conditional components, and warn before the wall rather than at it.
In short
WhenQuotaAvailable, WhenQuotaExhausted and WhenQuotaThreshold render on quota state, so the UI stops carrying quota logic in conditionals. The threshold component is the one that matters: warning at 80 percent converts, blocking at 100 percent churns.
The usual way quota logic enters a React codebase is one if at a time. Six
months later the rule lives in nine components and two of them are wrong.
The fix is to stop asking "how much is left" in each component and let the component render on quota state instead.
Before you start
A plan with a quota defined. The examples use the slug api-calls, matching
charging per API call.
Step one: render on state, not on numbers
import {
WhenQuotaAvailable,
WhenQuotaExhausted,
WhenQuotaThreshold,
} from '@buildbase/sdk/react';
function APISection() {
return (
<>
<WhenQuotaAvailable slug="api-calls">
<Playground />
</WhenQuotaAvailable>
<WhenQuotaExhausted slug="api-calls">
<p>Quota exhausted. Upgrade for more.</p>
</WhenQuotaExhausted>
</>
);
}What you should see: the playground while there is allowance left, the upgrade message once there is not. No conditional in your component, and no chance of one branch drifting from the other.
The full set:
| Component | Props | Renders when |
|---|---|---|
WhenQuotaAvailable | slug | Has remaining units |
WhenQuotaExhausted | slug | Fully consumed |
WhenQuotaOverage | slug | In overage |
WhenQuotaThreshold | slug, threshold | Usage at or above a percentage |
Step two: warn before the wall
This is the one that earns money, and most implementations skip it.
<WhenQuotaThreshold slug="api-calls" threshold={80}>
<Banner>You have used 80% of this month's API calls.</Banner>
</WhenQuotaThreshold>A customer who hits 100 percent mid-workflow experiences an outage they blame on you. Warn them at 80 percent and they experience a plan that is too small. Different feeling, different support ticket, same data.
PlugNode, our visual workflow builder, sells credits rather than seats, so this is the component doing the most work in its UI. A workflow that dies partway through because the credits ran out looks like the product broke. The same run, preceded by a banner, looks like a plan that needs upgrading. We put the threshold warning in before we put in the usage dashboard, and that order was right.
If you ship one thing from this post, ship the threshold warning.
Step three: show the number when it is decision-time
Conditional components handle most of the UI. On a settings or billing screen, people want the actual figure:
import { useAllQuotaUsage, useQuotaUsageStatus } from '@buildbase/sdk/react';useAllQuotaUsage is the one to reach for on a usage dashboard, since it avoids
a hook per quota as the plan grows.
Warning
None of this is enforcement. A user with devtools can render whatever they like. The server call that records usage is what actually stops the work - see charging per API call. Treat this layer as the explanation, not the lock.
What to avoid
Blocking the whole page. Gate the feature, not the app. A user at their limit still needs to reach billing, and if the upgrade path is behind the gate they cannot pay you.
Hiding the gate entirely. If a feature vanishes when quota runs out, the
user thinks it broke. WhenQuotaExhausted exists so the absence has an
explanation attached.
Refetching on every render. Quota state does not change between two keystrokes. Let the hooks handle their own cadence.
Install
npm i @buildbase/sdk