Where state lives
Four homes for data in a frontend, and the mistake of treating them as one.
State is just data that can change. The important question is never "what is the state" but "where is the authoritative copy", because everything else is a copy that can be wrong.
- The server
The truth. Everything else is cached from here. - The URL
Which page, which filters, which tab. Shareable and survives refresh. - Component memory
Is this dropdown open. Dies on refresh, and should. - The browser store
Preferences, drafts. Survives refresh, invisible to the server.
The category people get wrong is server state. Data fetched from an API is not really your app’s state. It is a cache of someone else’s state, and it goes stale the instant somebody else changes it. Treating it like local state is what produces the classic "I updated it but the list still shows the old value" bug.
What to remember
- Identify the authoritative copy first; everything else is a cache.
- Filters, tabs, and search terms belong in the URL.
- Server data is a cache with an expiry you did not choose.
Terms in this lesson
Field notes
Loaded from a deliberately slow source. The lesson above was already readable while this was still travelling. That is streaming, and it is the same trick a chat interface uses.
The bug was three caches deep
A team spent two days on a "deploy that did not work". The deploy was fine. A CDN rule was caching the HTML document itself for an hour, so every visitor kept getting the previous build. The fix was one header; finding it needed knowing the copies existed.
Reported by a solo founder, 2024
Nobody had opened the empty state
A product launched with a dashboard that looked superb with demo data and completely blank on day one. Every new signup saw an empty white rectangle and assumed the app was broken. Signup-to-activation doubled after a two-hour fix.
Common enough to be a cliché
resolved in 900ms · region iad1
Hide field notes toggles a search param the loader reads. With it off, the slow promise is never created, so nothing streams.