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

@zencemarketing/zence-react-native-sdk

v0.1.1

Published

Reusable React Native SDK to wrap any web app URL in a native WebView shell.

Readme

Zence React Native SDK — Client Integration Guide

Overview

The Zence React Native SDK lets you embed your existing reward portal (web app) inside native Android and iOS apps using a secure WebView container and a small native ↔ web bridge.

Component name: ZenceRewardPortal

Supported platforms: Android, iOS

Capabilities:

  • Secure SSO login (form POST or URL-based)
  • Dynamic WebView rendering
  • Web ↔ Native messaging
  • Pull to refresh
  • Android hardware back navigation
  • Offline fallback screen
  • Deep link forwarding
  • Optional push token handoff

SDK package

| Item | Value | |------|--------| | npm (scoped) | @zencemarketing/zence-react-native-sdk | | npm (unscoped) | zence-react-native-sdk | | Registry | https://www.npmjs.com/package/@zencemarketing/zence-react-native-sdk |

Use whichever package name is published for your environment. Examples below use the scoped name.


Prerequisites

| Requirement | Version | |-------------|---------| | React | >= 18 | | React Native | >= 0.72 | | react-native-webview | >= 13 | | Node (development) | >= 18 recommended |

| Platform | Supported | |----------|-----------| | Android | Yes | | iOS | Yes |


Installation

1. Install packages

npm install @zencemarketing/zence-react-native-sdk \
  react-native-webview \
  @react-native-community/netinfo
yarn add @zencemarketing/zence-react-native-sdk \
  react-native-webview \
  @react-native-community/netinfo

2. iOS — CocoaPods

cd ios && pod install && cd ..

3. Android

Ensure AndroidManifest.xml includes:

<uses-permission android:name="android.permission.INTERNET" />

4. iOS — App Transport Security

Production apps should use HTTPS. For non-standard TLS or HTTP in development, configure NSAppTransportSecurity in Info.plist as required by your policy.


Integration modes

The SDK supports two authentication patterns. Use the one your backend documents.

Mode A — Form SSO (recommended for Kotak / reward portal)

The mobile app passes a customer identifier from your backend. The SDK loads a bootstrap page that POSTs a hidden customer_number field to the SSO endpoint, then follows the server redirect into the portal.

Mobile App
    ↓
Backend returns customer_number (or signed token used as customer_number)
    ↓
ZenceRewardPortal (customerNumber + ssoUrl)
    ↓
SDK auto-submits POST form
    ↓
Backend validates → HTTP redirect
    ↓
Reward portal loads in WebView

Example (QA):

import React from "react";
import { ZenceRewardPortal } from "@zencemarketing/zence-react-native-sdk";

const CUSTOMER_NUMBER = "<FROM_YOUR_BACKEND>";
const SSO_URL =
  "https://{REWARD_PORTAL_BASE_URL}/auth/SSO?tenantid={YOUR_TENANT_NAME}";

export default function App() {
  return (
    <ZenceRewardPortal
      customerNumber={CUSTOMER_NUMBER}
      ssoUrl={SSO_URL}
      enableBackButton
      enablePullToRefresh
      offline={{ enabled: true }}
      onMessage={(data) => console.log("Web -> Native:", data)}
      onError={(error) => console.log("WebView Error:", error)}
    />
  );
}

What the SDK does internally:

var form = document.createElement("form");
form.method = "POST";
form.action = "<ssoUrl>";

var input = document.createElement("input");
input.type = "hidden";
input.name = "customer_number"; // override via sso.tokenField
input.value = "<customerNumber>";
form.appendChild(input);

document.body.appendChild(form);
form.submit();

Advanced SSO config:

<ZenceRewardPortal
  customerNumber={CUSTOMER_NUMBER}
  sso={{
    url: SSO_URL,
    method: "POST",              // default: POST
    tokenField: "customer_number", // default: customer_number
    extraFields: { channel: "MOBILE" },
  }}
/>

| Environment | SSO URL example | |-------------|-----------------| | QA / UAT | https://rp2-rewardportal.erzqa.com/auth/SSO?tenantid=kotak | | Production | Provided by Zence (HTTPS required) |


Mode B — URL SSO (JWT in query string)

If your tenant expects the token in the URL (not a form POST), load the portal directly:

import { ZenceRewardPortal } from "@zencemarketing/zence-react-native-sdk";

const jwt = "<JWT_FROM_BACKEND>";

<ZenceRewardPortal
  url={`https://domain.com/auth/sso?token=${jwt}`}
  enableBackButton
  enablePullToRefresh
  offline={{ enabled: true }}
  onMessage={(data) => console.log(data)}
  onError={(error) => console.log(error)}
/>

Production URL format:

https://domain.com/auth/sso?token=<JWT_TOKEN>

Backend token generation (JWT tenants)

For tenants that issue a signed JWT, generation must happen on your server — never in the mobile app.

Sample claims

| Claim | Description | |-------|-------------| | customerId | Unique customer identifier | | tenantId | Brand / tenant identifier | | channel | Platform source (e.g. MOBILE, WEB) | | requestId | Request tracking ID | | returnUrl | Post-login redirect path | | nonce | Random unique value |

Sample — .NET

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;

var claims = new[]
{
    new Claim("customerId", "C12345"),
    new Claim("tenantId", "kotak"),
    new Claim("channel", "MOBILE"),
    new Claim("requestId", "REQ7890"),
    new Claim("returnUrl", "/dashboard"),
    new Claim("nonce", "XYZ123")
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YOUR_SERVER_SECRET"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var token = new JwtSecurityToken(
    issuer: "kotak",
    audience: "rewards-portal",
    claims: claims,
    expires: DateTime.UtcNow.AddMinutes(5),
    signingCredentials: creds);

var jwt = new JwtSecurityTokenHandler().WriteToken(token);

Use the JWT either as:

  • Mode B: append to url query string, or
  • Mode A: pass the value (or a mapped identifier) as customerNumber if your SSO endpoint expects form POST.

Security recommendations

| Topic | Recommendation | |-------|----------------| | Token expiry | Short-lived tokens (e.g. 5 minutes) | | Signing | HMAC SHA256 (or as specified by Zence) | | Secrets | Never embed signing keys in the mobile app | | Transport | HTTPS only in production | | Validation | Always validate tokens on the backend |


Component props (ZenceRewardPortal)

Core

| Prop | Type | Default | Description | |------|------|---------|-------------| | customerNumber | string | — | Value POSTed as hidden customer_number (Mode A). | | ssoUrl | string | — | SSO endpoint URL (shorthand for sso.url). | | sso | SSOConfig | — | Full SSO config (url, method, tokenField, extraFields). | | url | string | — | Direct WebView URL (Mode B or non-SSO). Optional when using SSO props. | | token | string | — | Deprecated alias for customerNumber; also written to web localStorage / sessionStorage as "token" when set. |

UX & WebView

| Prop | Type | Default | Description | |------|------|---------|-------------| | enableBackButton | boolean | true | Android hardware back navigates WebView history. | | enablePullToRefresh | boolean | true | Pull-to-refresh on WebView. | | offline | OfflineConfig | — | Offline fallback when network is unavailable. | | loader | LoaderConfig | — | Loading overlay color / background. | | style | ViewStyle | — | Wrapper style. | | headers | Record<string, string> | — | HTTP headers for document load (URL mode). | | userAgent | string | — | Custom user agent. |

Callbacks

| Prop | Type | Description | |------|------|-------------| | onMessage | (message: BridgeMessage) => void | Parsed messages from the web app. | | onError | (error: string) => void | Load, HTTP, or bridge errors. | | onLoadStart / onLoadEnd | (url: string) => void | Navigation lifecycle. | | onNavigationStateChange | (state) => void | WebView navigation state. | | onAnalyticsEvent | (event) => void | Analytics hook. | | onDeepLink | (url: string) => void | App deep link received. | | onPushTokenRequested | () => Promise<string \| undefined> | Supply push token to web. |

Ref methods (NativeCommands)

| Method | Description | |--------|-------------| | postMessageToWeb(message) | Send structured message to the web layer. | | reload() | Reload WebView. | | goBack() | WebView back navigation. |


Offline configuration

offline={{ enabled: true }}

When enabled and the device is offline:

  • A fallback HTML screen is shown.
  • When connectivity returns, the SDK switches back to the main WebView automatically.

There is no manual “Retry” button in the default UI. You may supply custom HTML via offline.fallbackHtml.


Web → Native communication

Web (inside portal):

window.ReactNativeWebView.postMessage(
  JSON.stringify({
    type: "LOGIN_SUCCESS",
    payload: { customerId: "C12345" },
  }),
);

Native:

onMessage={(data) => {
  console.log("Message from Web:", data);
}}

Built-in message types

| type | Behavior | |--------|----------| | REQUEST_PUSH_TOKEN | Native calls onPushTokenRequested and injects PUSH_TOKEN_RESPONSE. |


Native → Web communication

import { useRef } from "react";
import { ZenceRewardPortal, type NativeCommands } from "@zencemarketing/zence-react-native-sdk";

const ref = useRef<NativeCommands>(null);

ref.current?.postMessageToWeb({
  type: "SET_THEME",
  payload: { theme: "dark" },
});

The web app can listen via:

window.ZenceBridge.onNativeMessage = (message) => {
  console.log("From native:", message);
};

window.addEventListener("zence-native-message", (event) => {
  console.log(event.detail);
});

Deep links are forwarded as { type: "DEEPLINK_RECEIVED", payload: { url } }.


Error handling

onError={(error) => {
  console.log("WebView Error:", error);
}}

Common causes:

  • Invalid or missing url / SSO configuration
  • Network failure
  • SSL / certificate issues
  • HTTP errors from SSO endpoint
  • Expired or invalid customer token

Production checklist

| Item | Status | |------|--------| | HTTPS enabled | Required | | Token / customer_number from backend only | Required | | Backend validation on SSO endpoint | Required | | Valid SSL certificate | Required | | Tested on Android | Required | | Tested on iOS | Required | | Release signing keystore (not debug) | Required for store builds |


Troubleshooting

White / blank screen

  • Verify ssoUrl or url is correct for your environment.
  • Check device network and onError logs.
  • Confirm ATS (iOS) / cleartext (Android) settings for non-HTTPS dev URLs.

SSO login fails

  • Confirm backend expects POST customer_number (Mode A) vs GET token in URL (Mode B).
  • Verify customerNumber value is current and not expired.
  • QA URL: https://rp2-rewardportal.erzqa.com/auth/SSO?tenantid=kotak

Messages not reaching native

  • Use window.ReactNativeWebView.postMessage with JSON.stringify.
  • Message must originate from JavaScript running inside the WebView.

Version information

| Item | Value | |------|--------| | npm version | 0.1.1 | | SDK name | Zence React Native SDK | | Component | ZenceRewardPortal | | Integration type | WebView hybrid | | Platforms | Android & iOS | | Primary auth (Kotak) | Form POST customer_number | | Alternate auth | JWT in URL query string |


Support

For SDK support or onboarding, contact the Zence technical team.


License

MIT — see LICENSE.