StatsHub Docs

Value Bets

Model price against the market's, on three boards that run at once — and the URL-to-query mapping that has to exist on both sides of the network.

RouteComposed
/value-betssrc/composed/value-bets
/value-bets-v2/[view]src/composed/value-bets-v2
/value-bets-v3/[view]src/composed/value-bets-v3

Three generations, on purpose

All three are live. A change to the model is judged against the board it replaces rather than against memory, which is the only way to tell an improvement from a difference.

v2 and v3 take a [view] segment — raw-model-outputs, teams-model, tracked, watchlist, maccas-settings — rather than a ?view= flag, so a saved link keeps working when the default changes. The redirects in next.config.js map the old query form onto it.

The URL is not the API's query

The two vocabularies differ, and there are eighteen of them: the address says q, market, leagues, minOdds; the endpoint wants search, marketType, uniqueTournamentId, minOdd.

That mapping used to be a useMemo over eighteen useQueryState values inside the client component, which was fine until the server had to build the same request. It now lives in its own module, deliberately free of nuqs — nuqs is client-only, and importing a module that touches it from a Server Component fails the build. It takes plain values in and returns the API's query out, so both sides can call it.

This is the general shape of the fix

Any board whose data is read on the server and filtered in the browser needs its URL-to-query mapping in a module neither side owns. super-sub-heroes/state.ts carries a comment about the same build failure, from the other direction.

V2 is the biggest surface in the product

4,900 lines, fifty-nine data calls, and a hundred and forty-six values the markup reads. The seam between state and view is a hook, not a prop list: a hand-written list of a hundred and forty-six props would be longer than most components and would need editing twice for every change.

useValueBetsV2 owns every request, every parser and every derivation; the view takes its return value whole and cannot reach the network. That is the boundary the convention is about, whether it arrives as ten props or a hundred and forty-six.

On this page