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-groov-sdk

v0.0.9

Published

Groov sdk for the webview

Downloads

7

Readme

Embed react native library

Overview

Groov’s Embed React Native library provides the set of screens and functionalities that enable applications to easily embed Groov enabled merchant journeys (across Groov Insights and Groov Capital). The library contains:

  • Personalised UX to guide your customers through the Connect and/or Capital lifecycle processes
  • Modular design to help you seamlessly embed the embedded features into your application's flow

This library needs to be used alongside the end to end implementation steps as details in https://docs.wearegroov.io/docs/integrate-via-groov-widget#/

Environments and testing with the library

Two environments exist to support the Groov library integrations:

  • 'sandbox' - to be used for testing with sample flows in your test application environment (if available).
  • 'live' - to be used only in production apps

The environment being used is determined by the API Keys that is used to generate the necessary library tokens.

Going Live

Once you are satisfied with your integration and are ready to go live, please access your Groov Admin Dashboard account to obtain the live API key. You will have to replace the sandbox API key in your code with the live API key. To use the correct API key, remember to toggle the Test vs Live viewing options on your Groov dashboard account..

Check that you have enabled the required configurations to enable the required features (Connect, Capital) inside your Groov Dashboard, before going live.

Adding the dependency

Groov’s React Native Library supports:

  • React Native 0.76
  • Axios 1.7.9
  • Android API level 33+
  • iOS?

Adding dependency through npm

Navigate to the root directory of your React Native project. The rest of this section will assume you are in the root directory. Run the following command:

$ npm install @wearegroov/react-native-embed --save

Sample implementation

This section focusses on an example on how you would integrate the Library component above in your main app codebase:

import ...;
import ...;
import { GroovWebView } from '@wearegroov/react-native-embed';
import * as GroovWebViewConfig from '../../../groov-webview-config';

//assume you want to toggle Groov widget on your app screen called PaymentsScreen,
//you would need to include rows starting <View... till ending with </View>
export const PaymentsScreen = () => (
    <View style={styles.screen}>
        <GroovWebView
            embedAppServerWidgetIdRouterEndpoint={GroovWebViewConfig.embedAppServerWidgetIdRouterEndpoint}
            embedAppServerAuthType={GroovWebViewConfig.embedAppServerAuthType}
            embedAppServerAuthValue={GroovWebViewConfig.embedAppServerAuthValue}
            embedAppServerAPIMethodType={GroovWebViewConfig.embedAppServerAPIMethodType}
            widgetFrameStyle={styles.groovWebViewContainer} //as an optional input if you wish to
        />
    </View>
);

const styles = StyleSheet.create({
    screen: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    //optional if you want to provide a custom styling
    groovWebViewContainer: {
        margin: 20,
        borderWidth: 1,
        borderColor: 'blue',
        borderRadius: 10,
        overflow: 'hidden',
    },
});

Styling customization

For both iOS and Android, the React Native Library uses the default white-labelling setup your platform has setup in your Groov Dashboard account.

You can provide a optional widget container styling to the library function as per the implementation example above.

Session Management

Once a merchant/user enters the app/screen context where the Groov Widget is housed, Groov automatically manages the start and end of a session. Everytime a new session is initiated, Groov generates a new session id in form of WidgetId in context of the user and associates it to the session identity for the duration of a particular session.

Support

Should you encounter any technical issues during integration, please contact Groov’s Customer Support team via email, including the word EMBED-ISSUE: at the start of the subject line.

Alternatively, you can search the support documentation available via our developer documentation portal, https://docs.wearegroov.io .

We will notify you of any major library releases and details can always be found via our developer documentation portal, https://docs.wearegroov.io .

How is the Groov’s React Native Library licensed?

The Groov React Native Embed Library is available under the ISC license.

Code Block changes in repo

config.js

export const GROOV_URI = 'https://app.wearegroov.io/api/v1/emca/merchant-identity';
export const GROOV_AUTH_KEY = 'x-api-key';

package.json

{
    "name": "react-native-embed",
    "version": "0.0.1",        
    "description": "Groov library for embedded react native component",        
    "main": "index.js",        
    "scripts": {        
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/wearegroov/react-native-embed"
    },
    "keywords": [
        "groov",
        "webview",
        "library",
        "react-native",
        "embedded-finance"
    ],
    "author": "Groov",
    "license": "ISC",
    "bugs": {
        "url": "https://github.com/wearegroov/react-native-embed/issues"
    },
    "homepage": "https://github.com/wearegroov/react-native-embed?tab=readme-ov-file#readme",
    "dependencies": {
        "axios": "^1.7.9",
        "react-native-get-random-values": "~1.11.0",
        "uuid": "^11.0.3",
        "react-native-webview": "13.12.5"
    },
    "peerDependencies": {
        "react": "18.3.1",
        "react-native": "0.76.5",
        "react-native-get-random-values": "~1.11.0",
        "uuid": "^11.0.3",
        "react-native-webview": "13.12.5",
        "axios": "^1.7.9",
        "@react-navigation/native": "^7.0.14"
    }    
}

index.js

import axios from 'axios';
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import { WebView } from 'react-native-webview';
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import * as config from './config';

export function GroovWebView({embedAppServerWidgetIdRouterEndpoint, embedAppServerAuthType, embedAppServerAuthValue, embedAppServerAPIMethodType, widgetFrameStyle = {} }) {
    const [groovEmbedComponentUrl, setGroovEmbedComponentUrl] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    
    useEffect(() => {
        registerWidgetAndLoadGroovEmbedComponent();
    }, []);

    async function registerWidgetAndLoadGroovEmbedComponent() {
        try {
            const gWidgetId = uuidv4();
            const institutionWidgetRegistrarEndpoint = `${normalizeUrl(embedAppServerWidgetIdRouterEndpoint)}/${gWidgetId}`;
            const headers = { [embedAppServerAuthType]: embedAppServerAuthValue };
            const method = embedAppServerAPIMethodType.toLowerCase();

            if (method === "get") {
                await axios.get(institutionWidgetRegistrarEndpoint, { headers });
            } else if (method === "put") {
                await axios.put(institutionWidgetRegistrarEndpoint, null, { headers });
            } else if (method === "post") {
                await axios.post(institutionWidgetRegistrarEndpoint, null, { headers });
            }

            const response = await axios.get(config.GROOV_URI, {
                headers: { [config.GROOV_AUTH_KEY]: gWidgetId }
            });

            setGroovEmbedComponentUrl(response.data.campaign.groovEmbedUrl);
        } catch (err) {
            console.error('Error while fetching Groov Embed URL:', {
                message: err.message,
                stack: err.stack,
                response: err.response?.data,
            });
            setError('Failed to load Groov Widget. Please try again later.');
        } finally {
            setLoading(false);
        }
    }

    function normalizeUrl(url) {
        return url.endsWith('/') ? url.slice(0, -1) : url;
    }

    if (loading) {
        return (
            <View style={styles.center}>
                <ActivityIndicator size="large" color="#0000ff" />
            </View>
        );
    }

    if (error) {
        return (
            <View style={styles.center}>
                <Text style={styles.errorText}>{error}</Text>
            </View>
        );
    }

    return (
        <View style={[styles.defaultContainer, widgetFrameStyle]}>
            <WebView
                source={{ uri: groovEmbedComponentUrl }}
                onError={(syntheticEvent) => {
                    const { nativeEvent } = syntheticEvent;
                    console.error('WebView error: ', nativeEvent);
                    setError('An error occurred while loading the WebView content.');
                }}
                javaScriptEnabled={true}
                domStorageEnabled={true}
                startInLoadingState={true}
            />
        </View>
    );
}

GroovWebView.propTypes = {        
    embedAppServerWidgetIdRouterEndpoint: PropTypes.string.isRequired,
    embedAppServerAuthType: PropTypes.string.isRequired,
    embedAppServerAuthValue: PropTypes.string.isRequired,
    embedAppServerAPIMethodType: PropTypes.string.isRequired,
};

const styles = StyleSheet.create({
    center: {
        flex: 1,            
        justifyContent: 'center',
        alignItems: 'center',
        padding: 20,
    },
    errorText: {
        color: 'red',
        fontSize: 16,
        textAlign: 'center',
    },
    defaultContainer: {
        flex: 1,
        width: '100%',
    },
});