npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-gleapsdk

v19.5.1

Published

Gleap SDK for React Native: AI customer support, live chat, in-app bug reporting and customer feedback.

Readme

Gleap React Native SDK

Gleap ReactNative SDK Intro

Add AI-native customer support, live chat, in-app bug reporting, a help center and surveys to your React Native apps with Gleap. Gleap is an Intercom alternative for software teams that connects customer conversations and feedback with product development.

SDK documentation · Website · Plans and pricing

Installation

npm install react-native-gleapsdk
cd ios && pod install

iOS requirements

  • iOS 15.0 or later
  • React Native 0.75 or later (Expo SDK 52 or later)

The native Gleap iOS SDK is installed with Swift Package Manager: pod install adds the Gleap-iOS-SDK package (product Gleap) to the Pods project through React Native's spm_dependency, and Xcode resolves it on the next build. You don't add the package to your app yourself. Your Podfile must call react_native_post_install in its post_install hook, as the React Native and Expo templates do.

pod install logs a warning that a Swift package with static linking "might cause linker errors". You can ignore it: the SDK builds with the default static linkage as well as with USE_FRAMEWORKS=dynamic.

On React Native older than 0.75, pod install falls back to the Gleap pod from CocoaPods trunk and prints a warning. CocoaPods trunk is read-only from December 2, 2026, so only versions released before then are available this way.

Usage

// Import the SDK
import Gleap from "react-native-gleapsdk";

// Initialize it with your Project ID
Gleap.initialize('YOUR_PROJECT_ID');

Find the Project ID in the Gleap dashboard under Settings → Project → General. It was called "SDK key" or "API key" before; the value is the same and existing keys keep working.

Data regions

Gleap projects are hosted in the EU by default. If your project lives in the US region, set the region before calling initialize:

Gleap.setRegion("us"); // "eu" (default) | "us"
Gleap.initialize('YOUR_PROJECT_ID');

setRegion sets the API, websocket and realtime hosts at once. For dedicated servers you can still override a single host afterwards with setApiUrl, setWSApiUrl or setRealtimeHost.

Env data

With every ticket the SDK sends env data (device model, OS version, screen size, locale, battery state, …), shown under the Env data tab in Gleap. Leave out individual keys or stop collecting env data entirely:

Gleap.setEnvDataPropsToIgnore(['deviceName', 'batteryLevel']);
Gleap.setDisableEnvData(true);

Both can be called at any time and apply to the next ticket. Each setEnvDataPropsToIgnore call replaces the previous list, an empty array resets it. setDisableEnvData(false) turns the collection back on.

Dark mode

Switch the widget between dark and light mode. auto follows the device appearance; if your app has its own theme toggle, pass light or dark explicitly and call it again whenever the theme changes:

Gleap.setColorScheme('auto');
Gleap.setColorScheme(isDarkTheme ? 'dark' : 'light', { darkBackgroundColor: '#121212' });

setColorScheme only takes effect when "Adapt to dark / light mode" is enabled in the Gleap dashboard; it then overrides the dashboard's color scheme. Before the first call the dashboard setting applies. In dark mode the widget uses the dark mode colors, logo, header image and composer glow set in the Gleap dashboard; without dark colors it keeps its normal colors. lightBackgroundColor / darkBackgroundColor override the background in light / dark mode. Can be called before or after initialize.

Inline banners

Inline banners (the banner style set in the Gleap dashboard) sit at the top of the screen and cover the status bar. To push your app down below them instead of covering it, like inline banners on the web, wrap the app in GleapBannerArea:

import Gleap, { GleapBannerArea } from 'react-native-gleapsdk';

export default function App() {
  return (
    <GleapBannerArea>
      <NavigationContainer>{/* ... */}</NavigationContainer>
    </GleapBannerArea>
  );
}

While an inline banner is shown, the content moves down by the banner's height (animated) and back up when it closes; floating banners still float above the app. Without GleapBannerArea nothing changes: banners overlay the app as before.

The banner already covers the status bar, so screens that add the top safe-area inset themselves (React Navigation headers, SafeAreaView) would leave a gap below it. With react-native-safe-area-context, hand them the inset that is left:

import { SafeAreaInsetsContext, useSafeAreaInsets } from 'react-native-safe-area-context';
import { GleapBannerArea, useGleapBannerHeight } from 'react-native-gleapsdk';

function BannerSafeArea({ children }) {
  const insets = useSafeAreaInsets();
  const bannerHeight = useGleapBannerHeight();
  return (
    <SafeAreaInsetsContext.Provider value={{ ...insets, top: Math.max(0, insets.top - bannerHeight) }}>
      {children}
    </SafeAreaInsetsContext.Provider>
  );
}

// <SafeAreaProvider><GleapBannerArea><BannerSafeArea><NavigationContainer>…

useGleapBannerHeight() returns the height (points on iOS, dp on Android, measured from the top edge; 0 while no inline banner is shown) for custom layouts; Gleap.getBannerHeight() and the bannerHeightChanged listener (Gleap.registerListener('bannerHeightChanged', (height) => …)) give the same value.

Network logs

Network logs are recorded when they are turned on in the Gleap dashboard, or after you call Gleap.startNetworkLogging(). Gleap.stopNetworkLogging() turns them off again, also when the dashboard turns them on.

  • iOS: the native SDK records every request of the app, including requests made by native modules.
  • Android: the SDK records fetch and XMLHttpRequest requests (and libraries built on them, such as axios) in JavaScript and hands them to the native SDK.

Leave requests out or remove data before it leaves the device:

Gleap.setNetworkLogsBlacklist(['analytics.example.com']);
Gleap.setNetworkLogPropsToIgnore(['password', 'token', 'user.email']);

setNetworkLogsBlacklist drops every request whose URL contains one of the strings. setNetworkLogPropsToIgnore removes headers, JSON keys (at any depth; a dotted name such as user.email also works as a path from the root), form fields and query parameters with these names, case-insensitively. Authorization, Proxy-Authorization, Cookie and Set-Cookie headers are always masked, and requests to Gleap itself are never logged. Each call replaces the previous list. Bodies over 150 KB are cut; binary and streaming bodies (images, server-sent events, …) are left out.

Sign in users (identity tokens)

Your backend signs a short HS256 JWT with an identity key from Settings → Security → Customer identity → Identity keys (put the key id in the kid header; the secret never leaves your server). The userId claim is required. Optional claims: email, name, company ({ id, name }), plan, and provider ids such as stripeCustomerId. Set exp to at most one hour. Everything in the token lands on the contact as signed data the app cannot change. Pass the token to the SDK with setUserJwt after login and on every app start of a logged-in user; no separate identify call is needed, and the token is kept in memory only. The optional setUserJwtProvider fetches a fresh token when it expires and, with the native 19.5.0 SDKs, restores the signed session after an app restart. Call clearIdentity on logout. setAuthTokens hands Kai your own API tokens for this user. See Customer identity and React Native user identity.

// After login and on every app start of a logged-in user
await Gleap.setUserJwt(token);

// Called when the token has expired or is about to; return a fresh one
Gleap.setUserJwtProvider(async () => {
  const response = await fetch('https://api.example.com/gleap-token', {
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  const { token } = await response.json();
  return token;
});

// Optional: shorten the signed session (milliseconds)
Gleap.setSessionDuration(24 * 60 * 60 * 1000);

// Optional: tokens API tools may use to call your backend as this user (null removes one)
await Gleap.setAuthTokens({ backend: accessToken });

// On logout
Gleap.clearIdentity();

setSessionDuration(ms) shortens the signed session; the project's maximum applies.

setUserJwt resolves once the native SDK has the token, not when the server accepted it. Refusals (token_expired, token_invalid, signature_required) are logged by the native SDK: look in the Xcode console and in logcat under the tag Gleap, not in Metro. A token re-minted with the same claims (only iat/exp differ) is not sent again.

The identity handling runs in the native iOS and Android SDKs, so their behaviour applies here as is: setUserJwt and setUserJwtProvider may be called before or after initialize (a token is sent once the SDK starts), a returning user on a project that switched to Signed gets the identify of this app start sent once to obtain a signed session, and a short session duration is renewed at half its lifetime.

getIdentity() returns the contact the native SDK knows (user id and contact fields); it never contains the identity token or the grant.

Gleap.identify(userId, userProperties) without a token creates an unsigned contact.

Older integrations that pass a user hash to identifyWithUserHash keep working while "Accept legacy user hash" stays on in the project's security settings; see Upgrade to identity tokens.

Protected conversation files

With "Protect new files" (Settings → Security → Conversation files, see Authenticated conversation files), conversation files can only be opened by agents and by the verified customer the conversation belongs to. The SDK supports it without extra setup, as long as the app identifies the customer with a signed identity on every app start (Gleap.setUserJwt; older integrations that pass a user hash keep working).

A signed identify gives the session a short-lived file access token, which the native SDK keeps in memory only and renews while the app is in use. clearIdentity revokes it. Guests and contacts identified without a signed identity see "Sign in to view" instead of the file.

Email replies link attachments to your customer application URL with a gleapFile query parameter. If that URL opens your app (universal link / App Link), pass it to Gleap; the conversation opens once the customer is identified with a signed identity:

import { Linking } from 'react-native';

Linking.getInitialURL().then((url) => {
  if (url) {
    Gleap.openProtectedFileFromUrl(url);
  }
});
Linking.addEventListener('url', ({ url }) => {
  Gleap.openProtectedFileFromUrl(url);
});

openProtectedFileFromUrl resolves true if the URL carries a Gleap file reference and false otherwise. The link alone grants no access; keep the parameter through your app's login flow.

Need help?

Checkout our full documentation or contact us - we are always here to help 👋.