Persist React Query cache to localStorage to soften the unauth API ceiling#10
Conversation
|
Warning Rate limit exceeded
To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request implements client-side persistence for React Query by adding the @tanstack/react-query-persist-client and @tanstack/query-sync-storage-persister dependencies. The App component was updated to use PersistQueryClientProvider with a localStorage persister and a 24-hour garbage collection time. Feedback was provided to wrap the window.localStorage access in a try...catch block to ensure the application remains robust in environments where storage access might be restricted or disabled.
I am having trouble creating individual review comments. Click here to see my feedback.
src/App.tsx (22-25)
Accessing window.localStorage can throw an exception in certain environments, such as when a user has disabled storage for the site or is using a browser in a privacy mode that restricts storage access. This could cause the application to crash on startup for some users.
To make the application more robust, it's best to wrap the access to window.localStorage in a try...catch block. If localStorage is unavailable, you can pass undefined to createSyncStoragePersister, which will gracefully disable persistence without crashing the app.
const persister = createSyncStoragePersister({
storage: (() => {
try {
return window.localStorage;
} catch {
return undefined;
}
})(),
key: 'stardust-query-cache',
});
GitHub's unauth API quota (60 req/h) is the practical bottleneck for this site, and a single hard refresh hits 10 languages × 1-2 queries. Wrap the app in PersistQueryClientProvider so successful responses survive reloads for 24h, falling back to a network request only when the entry is missing or stale. gcTime is bumped to match maxAge so entries are not evicted from the in-memory cache before they can be rehydrated. The buster string lets future schema changes invalidate stored caches without manual user cleanup.
b74e3b8 to
df4fb1d
Compare
…t throw Older Safari private mode and browsers with site data disabled can throw on the very first `window.localStorage` property access (not just on getItem/setItem), which would have crashed the app at boot under PersistQueryClientProvider. Wrap the access in try/catch and fall back to undefined — createSyncStoragePersister treats that as 'no persistence' rather than crashing.
Summary
Unauthenticated GitHub API gives 60 req/h, and a hard refresh of stardust currently fans out to 10 languages × (1 preview + sometimes 1 full) requests, so a couple of reloads is enough to start hitting 403s. Authenticating client-side from a static GitHub Pages bundle is not safe (any token in the bundle is public), so the practical lever is to stop re-fetching things we already have.
This wraps the app in
PersistQueryClientProviderfrom@tanstack/react-query-persist-clientand alocalStoragepersister:maxAge— successful responses survive reloads for a daygcTimebumped to matchmaxAge; otherwise the in-memory cache evicts entries before persistence can rehydrate thembuster: 'v1'so we can invalidate stored caches if the schema changes@tanstack/query-sync-storage-persister,@tanstack/react-query-persist-client); bundle goes from 370KB → 374KB (+118KB → +118KB gzipped, no real movement)Per-query
staleTime: 1his unchanged, so the freshness story is the same — this only changes what happens between sessions and across hard reloads.Test plan
npm run lintnpm audit --omit=dev --audit-level=highnpm run buildnpm run test -- --runstardust-query-cachefrom localStorage, reload, confirm fresh fetch