Field Notes

State Management

Three-Tier State Management: URL, Zustand, and TanStack Query

Rillex Casino uses three state layers: the URL for shareable UI state, Zustand for client-only state, and TanStack Query for server data. This gives its 22 feature modules clear boundaries instead of one overloaded store.

Topic
State Management
Year
Read
7 min
Connected
Rillex Casino

The problem

Rillex Casino home pagesystem cut
The home view with the game catalogue, banners, and live balance.
Proof from Rillex CasinoOpen system

The solution

I split the state into three tiers. Each tier has a clear job.

Tier 1: URL state

  • Active tabs, filters, sort order, and pagination cursors
  • Modal triggers such as ?modal=login and ?modal=deposit
  • Game category and provider filters
  • useQueryParam(key, defaultValue) uses replaceState and useSyncExternalStore so updates stay synchronous without routing through Next.js

Tier 2: Zustand

  • Seven isolated stores: authStore, walletStore, uiStore, platformStore, chatStore, notificationStore, and liveBetsStore
  • Each feature owns its slice. For example, chatStore does not need walletStore.
  • Sensitive persisted data, including auth tokens and the user object, is stored in localStorage with AES-GCM encryption
  • The rillex-auth BroadcastChannel keeps login, logout, and token refresh in sync across tabs

Tier 3: TanStack Query

  • Typed key factories per feature, including gamesKeys.list(filters), walletKeys.balance(), and bonusKeys.active()
  • All 33 WebSocket event types map to query keys. deposit_confirmed invalidates walletKeys.all; bonus_wagering_update invalidates bonusKeys.all.
  • Server components prefetch with a QueryClient singleton and React.cache, then dehydrate through HydrationBoundary. Games, banners, and SEO data are therefore available without a second client request.

Why this works

The tiers do not duplicate state. The URL holds shareable UI state, Zustand handles client-only details like toasts, sidebar state, and chat drafts, and TanStack Query owns API data. When a feature is added, there is a sensible place for it to live.

Continue conversation

Frontend problem worth thinking through?

Bring the context, including the hard parts. I am happy to talk them through.