DocsMobile apps

React Native SDK

Pure-JS SDK for React Native and Expo — hooks for screens and targets, and the launcher.

Pure JavaScript — no native modules, no pod install, no linking — so it works with Expo out of the box. One package covers iOS and Android. Requires React Native ≥ 0.70 or Expo SDK ≥ 49, and ships with TypeScript types.

1. Install

Terminal
npm install github:lovelysomething/tooltip-tour-react-native

Plus these peer dependencies, if you don’t already have them:

Terminal
npm install react-native-svg react-native-safe-area-context @react-native-async-storage/async-storage

2. Configure and add the launcher

Call TooltipTour.configure() once before your root renders, and put TTLauncherView inside your GestureHandlerRootView so overlay coordinates line up.

import { TooltipTour, TTLauncherView } from 'tooltip-tour-react-native'
import { NavigationContainer } from '@react-navigation/native'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
import { SafeAreaProvider } from 'react-native-safe-area-context'

TooltipTour.configure({
  siteKey: 'sk_xxxxxxxxxx',
  baseURL: 'https://app.lovelysomething.com',
})

export default function App() {
  return (
    <SafeAreaProvider>
      <GestureHandlerRootView style={{ flex: 1 }}>
        <NavigationContainer>
          <RootNavigator />
        </NavigationContainer>
        <TTLauncherView />
      </GestureHandlerRootView>
    </SafeAreaProvider>
  )
}

3. Register screens and targets

HomeScreen.tsx
import { useTTPage, useTTTarget } from 'tooltip-tour-react-native'

export default function HomeScreen() {
  useTTPage('home')                              // this screen

  const titleRef  = useTTTarget('welcomeTitle')   // step targets
  const buttonRef = useTTTarget('getStartedButton')

  return (
    <View style={{ flex: 1, padding: 24 }}>
      <Text ref={titleRef}>Welcome</Text>
      <TouchableOpacity ref={buttonRef as any}>
        <Text>Get started</Text>
      </TouchableOpacity>
    </View>
  )
}
import { Linking } from 'react-native'
import { TooltipTour } from 'tooltip-tour-react-native'

useEffect(() => {
  Linking.getInitialURL().then(url => { if (url) TooltipTour.handleDeepLink(url) })
  const sub = Linking.addEventListener('url', ({ url }) => TooltipTour.handleDeepLink(url))
  return () => sub.remove()
}, [])

The Inspector QR code opens a link of the form scheme://inspect?session=…&base=…, so your app needs a URL scheme registered ("scheme" in Expo’s app.json, or an intent-filter in a bare app). Don’t use tooltiptour — it’s reserved for the native iOS and Android SDKs.

  1. Register a scheme in your app
    For example acmeapp: "scheme" in Expo’s app.json, or an intent-filter (Android) and URL Types (iOS) in a bare app.
  2. Save it in the dashboard
    Open Admin → App Guides → React Native from your React Native site, and enter the same scheme under URL scheme. Just the name — no ://.

Until a scheme is saved, Capture from device asks you to set one first. You can always type identifiers into the step editor instead.

5. Scrollable screens

Register a scroll callback per screen so the SDK can bring off-screen targets into view before spotlighting them:

HomeScreen.tsx
import { TooltipTour, TTViewRegistry } from 'tooltip-tour-react-native'

const scrollRef = useRef<ScrollView>(null)

useEffect(() => {
  TooltipTour.registerScrollable('home', (targetId) => {
    const elemRef = TTViewRegistry.getRef(targetId)
    if (!elemRef?.current || !scrollRef.current) return
    elemRef.current.measureLayout(
      scrollRef.current as any,
      (_x: number, y: number) => {
        scrollRef.current!.scrollTo({ y: Math.max(0, y - 120), animated: true })
      },
      () => {}
    )
  })
}, [])

The first argument must match the screen’s useTTPage() identifier.

Session lifecycle hooks

TypeScript
TooltipTour.onSessionStart(() => {
  // e.g. pause background audio, disable nav gestures
})
TooltipTour.onSessionEnd(() => {
  // e.g. resume audio, re-enable gestures
})
Something missing or unclear? Tell us and we’ll fix the page.