Skip to main content
useTapQuery reads the owner’s Tappify data. useTapServer calls one of your declared procedures. Both return the same object, cache per install and input, dedupe across mounts, and need no data library of your own.
Both give you { data, error, isLoading, refetch }. A result stays fresh for 30 seconds before the next mount asks again, and a failed call is not retried — refetch() is yours to call.

The queries you can run

Reads come from Tappify’s own database, never live from the App Store or Google Play, so a query is fast and cannot be rate-limited by a store. A query whose scope the owner has not granted is refused before it reaches the data: nothing comes back, and the hook’s error names the scope that kind needs. Ask the bridge first when a surface is optional:

Options

tap.invalidate("getSummary") invalidates one procedure by name across every mount; tap.invalidate() invalidates everything of yours.

One request per input, not per mount

Two widgets that ask for the same series in the same range make one request. The cache key is the install, the query and the filters behind it, so the same numbers render the same way in the slot, in the expand panel and in the tab. A procedure call carries tap.filters for you. A data query carries only the country picker — range and platform are the ones you put in the query, which is why the sample above passes filters.range. See Follow the page’s filters.