@guidelytech/react-native
v0.8.0
Published
Guidely for React Native: in-app tours, tooltips, checklists, surveys and a resource center rendered with native components
Maintainers
Readme
@guidelytech/react-native
Guidely for React Native and Expo: product tours, tooltips, spotlights, hotspots, banners, checklists, surveys and a resource center, authored in the Guidely dashboard and rendered with native React Native components. Pure JavaScript (no native module), so it works in Expo Go, development builds and bare React Native 0.72+.
npm install @guidelytech/react-native @react-native-async-storage/async-storageSetup
import AsyncStorage from "@react-native-async-storage/async-storage";
import { NavigationContainer, useNavigationContainerRef } from "@react-navigation/native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { GuidelyProvider, guidelyScreenLayout, useGuidelyNavigation } from "@guidelytech/react-native";
export default function App() {
const navigationRef = useNavigationContainerRef();
return (
<GuidelyProvider
projectId="pk_prod_xxx" // Settings → Environments
apiUrl="https://guidelytech.com"
storage={AsyncStorage} // persists identity, guide history and queued events
insets={useSafeAreaInsets()}
user={user ? { id: user.id, traits: { plan: user.plan, role: user.role } } : null}
onNavigate={(url) => routeInsideApp(url)} // relative / custom-scheme links from guides
>
<Navigation navigationRef={navigationRef} />
</GuidelyProvider>
);
}
function Navigation({ navigationRef }) {
const guidely = useGuidelyNavigation(navigationRef); // route changes → screen views
return (
<NavigationContainer ref={navigationRef} {...guidely}>
<Tab.Navigator screenLayout={guidelyScreenLayout}>{/* screens */}</Tab.Navigator>
</NavigationContainer>
);
}- Put the provider at the root, outside navigators, so guides draw above every screen.
- Guides reach the app only when iOS and/or Android is ticked under Trigger → Platforms in the guide editor.
- Screens: route names become screen names. URL patterns in the dashboard match the screen path
/<RouteName>. Without React Navigation callguidely.screen("Name")oruseGuidelyScreen("Name")yourself. screenLayout={guidelyScreenLayout}(React Navigation 7) tells Guidely which screen each target is on. Navigators keep inactive tabs mounted, so without it a tooltip could point at a button on a hidden tab. Elsewhere, wrap a screen in<GuidelyScreenScope name="Deals">.
Targets
import { GuidelyTarget, useGuidelyTarget } from "@guidelytech/react-native";
<GuidelyTarget id="new-deal-button" style={{ alignSelf: "flex-start" }}>
<Button title="New deal" onPress={create} />
</GuidelyTarget>
// or without a wrapper view
const target = useGuidelyTarget("pipeline-summary");
<View {...target} style={styles.card}>…</View>In the editor, choose the Guidely id selector kind and enter the same id. On the web the same
id is data-guidely-id, so one guide can target web and mobile. Taps on targets are observed, never
intercepted (they drive Element clicked triggers, click-to-advance steps and click checklist
tasks).
API
| | |
|---|---|
| useGuidely() | Client: identify(id, traits?, account?), setAccount, updateTraits, reset(), track(name, props?), screen(name), startGuide(idOrKey), stopGuide(), dismissGuide(), openChecklist(key), closeChecklist(key), completeChecklistTask(key, taskId), openResourceCenter(), closeResourceCenter(), refresh(), setConsent(), on(event, cb), getGuides(), getActiveGuide(), getState() |
| useGuidelyReady() | true once config is loaded |
| useGuidelyIdentify(id, traits?, account?) | Identify when the signed-in user changes |
| useGuidelyScreen(name) | Report a screen view from a component |
| useGuidelyNavigation(ref, { screenName? }) | React Navigation bridge (onReady, onStateChange) |
| useGuidelyEvent(name, cb) | Subscribe to ready, guide:start, guide:step, guide:complete, guide:dismiss, guide:skip, checklist:task, checklist:complete, survey:submit, resource-center:open, track, identify, error |
| useChecklistProgress(key), useGuideState(key), useActiveGuide() | Live state |
| <GuidelyTarget id>, useGuidelyTarget(id) | Guide targets |
| <GuidelyScreenScope name>, guidelyScreenLayout | Screen scoping for targets |
Provider props: projectId, apiUrl, environment, storage, user, debug, analytics,
consent (granted / pending / denied), appVersion (for App version rules), theme,
configRefreshMs, onNavigate, onError, showChecklistLauncher (default true),
showResourceCenterLauncher (default false), showMessengerLauncher (default true), insets,
launcherOffset (default 72).
Feature flags
Built in, with the same projectId — nothing to configure:
import { Feature, FeatureValue, useFeatureValue, useFlag, useGuidely } from "@guidelytech/react-native";
function Checkout() {
const newCheckout = useFlag("new-checkout"); // boolean flags
const color = useFeatureValue("checkout-button-color", "blue"); // string / number / JSON
return (
<Feature flag="new-dashboard-banner" fallback={<OldBanner />}>
<NewBanner />
</Feature>
);
}
useGuidely().isFeatureEnabled("new-checkout"); // or getFeatureValue / getFeatureDetails / flagsFlags evaluate on the device with id (user id, else the anonymous id), anonymousId, identify
traits, account, $audiences, screen, path, platform (ios / android), deviceType,
appVersion, locale and environment, plus flagAttributes from the provider. The last payload
is kept in storage, so flags work offline from a cold start; they refresh when the app returns to
the foreground. Experiment exposures are tracked as experiment_viewed events.
| | |
|---|---|
| useFlag(key, fallback = false), useFeatureValue(key, fallback), useFlagDetails(key, fallback), useFlags(), useFlagsReady(), useFlagsClient() | Hooks (same as @guidelytech/react). |
| <Feature flag fallback> (alias <FeatureFlag>), <FeatureValue flag value fallback> | Conditional rendering. |
| <FlagsProvider sdkKey storage attributes> | Flags only, without guides or analytics. |
| Provider props flagAttributes, flagsPayload, flags | Extra attributes; a bootstrap payload; false or flags client options. |
Scout messenger
When Scout is on for iOS/Android (dashboard → Scout → Show it on), a chat bubble opens a native messenger sheet (Home, Messages, Help). Scout's replies stream in with article citations and "Show me" guide buttons; team replies arrive while the thread is open, and the bubble shows an unread badge.
const guidely = useGuidely();
guidely.openMessenger(); // or "home" | "messages" | "help"
guidely.showNewMessage("I need help with exports");
guidely.closeMessenger();
useGuidelyEvent("conversation:message", ({ message }) => console.log(message.body));showMessengerLauncher={false} hides the bubble so you can open the messenger from your own UI.
openResourceCenter() opens the Help tab while the messenger is on, and reset() forgets the
install's conversations.
Behaviour
Config is cached in storage with an ETag and refreshed every 5 minutes and when the app returns to
the foreground; guides keep working offline. Events are queued, batched and retried; a new
session starts after the project's inactivity timeout. The SDK never throws into your app — errors
go to onError and, with debug, the console.
Full guide: docs/mobile.md. Example app: mobile/react-native/example.
