Graine AI

Launcher visibility

Where the launcher appears, when it shows, and how it is positioned — route groups, delays, continuity and insets.

Use this once you have a working React Native integration. "Show the button on these screens" survives about a week of real product work. Then: not on login; not until they have been there long enough to be stuck rather than reading; do not pop in again between steps of one flow; sit above the tab bar here and not there.

Requirements

GraineProvider must wrap NavigationContainer and share the same navigationRef. Without that the provider cannot observe route changes and none of this applies.

The simple case

<GraineProvider navigationRef={navigationRef} includeScreens={["Home", "Settings"]}>

Route names are case-sensitive and must match your navigator exactly. Omit includeScreens and every screen is eligible.

Add a global delay with launcherDelayMs={1500}.

Groups

When one flow needs different rules from another:

<GraineProvider
  navigationRef={navigationRef}
  visibility={{
    defaultDelayMs: 1200,
    defaultInset: { right: 16, bottom: 20 },
    groups: [
      {
        id: "kyc",
        screens: ["Step1", "Step2", "Step3"],
        continuity: "continuous",
        delayMs: 1500,
        delayPolicy: "oncePerGroupEntry",
        inset: { right: 16, bottom: 54 },
      },
      {
        id: "confirmation",
        screens: ["Done"],
        continuity: "perScreen",
        delayMs: 1500,
        delayPolicy: "oncePerAppSession",
      },
    ],
  }}
>

Continuity

ValueMeaning
continuousMoving between screens in this group keeps the launcher where it is
perScreenEach screen is decided independently

A multi-step form is one place as far as the customer is concerned. Re-running the delay on every step makes the launcher flicker in and out five times during a single KYC journey.

Delay policy

ValueWhen the delay runs
perScreenEvery time they land on a screen in the group
oncePerGroupEntryOnce on entering the flow; free inside it
oncePerAppSessionOnce per app run

Insets

{ top?, right?, bottom?, left? }, per group or as defaultInset. Use it to clear tab bars and bottom sheets. Defaults to { right: 16, bottom: 20 }.

What actually happens

Walked through a real journey with the config above:

route    eligible  delay    group         note
Login    no        —        —             not listed anywhere
Home     yes       1200ms   —             default, belongs to no group
Step1    yes       1500ms   kyc           group entry
Step2    yes       0ms      kyc           continuous — no flicker
Step3    yes       0ms      kyc           continuous
Done     yes       1500ms   confirmation  first visit this session
Home     yes       1200ms   —             left the group
Step1    yes       1500ms   kyc           re-entry counts as a new visit
Done     yes       0ms      confirmation  oncePerAppSession already spent

Rules worth knowing

  • Screens in any group count as included, even if you omit them from includeScreens. The final set is the union, so groups alone are enough.
  • With no rules configured at all, everything is eligible. An SDK that hides its own launcher until it is configured looks broken on the first run.
  • Leaving a group ends the visit, so returning later is a fresh entry and oncePerGroupEntry means what it says.

Hiding it on sensitive flows

Leave auth and payment-entry screens out of includeScreens and out of every group. There is no separate "exclude" list on purpose: a screen is shown the launcher because a rule named it, never because no rule excluded it.

Troubleshooting

SymptomWhat to check
Never appearsnavigationRef is the same ref as on NavigationContainer; the route is in includeScreens or a group; a delay may still be running
Appears on the wrong screensRoute names are case-sensitive — Step1, not step1
Delay "only happened once"oncePerGroupEntry or oncePerAppSession is working as designed
Overlaps the tab barSet inset.bottom for that group, or defaultInset

On this page