twocents/open source

Capturing app states

Open modals, sheets, tabs, and steps through debug-only hooks.

Use useSnapbotState for UI with no route of its own, such as a modal. A screenshot's state in snapbot.json reaches the app as ?snapbot=key (or key:value, comma-separated for several):

import { useSnapbotState } from "react-native-snapbot";

useSnapbotState("settings.filter", {
  open: () => setFilterVisible(true),
  close: () => setFilterVisible(false),
});

useSnapbotState("onboarding.step", {
  open: (stepId) => goToStep(stepId),
});

useSnapbotState("feed.report", {
  ready: Boolean(firstPost),
  open: () => openReport(firstPost),
  close: () => closeReport(),
});
  • open runs about 600 ms (SNAPBOT_OPEN_DELAY_MS) after its key arrives, so navigation started by the same deep link can finish; iOS ignores a modal presented while another screen is still animating away. It also runs on mount if the key is already active, so a sheet inside another sheet can open once its parent renders it.
  • close runs when a later deep link drops the key. Snapbot opens its setup route between captures, dropping active keys. Provide a close handler to reset UI that would otherwise remain open.
  • ready (a boolean, or a function of the value) holds open until the data the UI shows has loaded.
  • Prefer the screen's existing open handler over setting visibility directly, so captures match what a real tap shows, and only expose actions that cannot change real data.

The hook does nothing outside __DEV__.

Request states in configuration

{
  "name": "room-reactions",
  "deeplink": "example://rooms",
  "state": ["rooms.openFirstRoom", "room.allReactions"],
  "optional": true
}

This screenshot entry belongs in the config's screenshots array. Use state instead of manually adding snapbot to the deep link. Keys accept letters, digits, dots, underscores, and hyphens. An optional value follows : and must be nonempty and contain no comma. A state array must contain at least one entry. Use distinct keys; repeated keys are parsed into a map and the last value wins.

Multiple states request a set of UI states, not a guaranteed sequential action queue. Use mounting and ready to coordinate nested or data-dependent UI. The exported parseSnapbotStates helper parses the deep-link state map; SNAPBOT_STATE_PARAMETER is snapbot, and SNAPBOT_OPEN_DELAY_MS is 600.

The setup link between captures drops active keys. Supply close when an open handler leaves persistent UI state that needs resetting. Without it, UI your app opened may remain visible.

optional: true is retained as result metadata. It does not skip navigation failures or enable a different timeout policy: stability timeouts warn for all screenshots. See CLI and output.

On this page