React SDK

How to install and integrate the Stigg React SDK on the client-side

Overview

The Stigg React SDK is a Javascript library for implementing pricing and packaging in React apps with Stigg. it provides plug and play components and custom React hooks.
It's built on top of the JavaScript SDK and is the recommended method for integrating Stigg into your React application.

πŸ“š

Full SDK reference ↗️

Installing the SDK

You have a few options for using the @stigg/react-sdk package in your project:

From npm:

npm install @stigg/react-sdk
yarn add @stigg/react-sdk

Retrieving the client API key

In the Stigg Cloud Console, go to Settings > Account > Environments.

Copy the Client API key of the relevant environment.

Getting started

First, you'll need to wrap your application in a single StiggProvider component. that will provide the React Context to components that are placed inside your application:

import { StiggProvider } from '@stigg/react-sdk';

export function App() {
  return (
    <StiggProvider apiKey="<STIGG_CLIENT_API_KEY>">
      <NestedComponents />
    </StiggProvider>
  );
}

Importing the styles

If you plan to use the widget components, add an import statement to include the bundled styles:

import '@stigg/react-sdk/dist/styles.css';

Setting the customer context

Set the customer ID of the user that's accessing your app, usually after the customer signs in or restores a session.
The customerId can be passed to the StiggProvider component:

import { StiggProvider } from '@stigg/react-sdk';

export function App() {    
  return (
    <StiggProvider apiKey="<STIGG_CLIENT_API_KEY>" customerId={user.id}>
      <NestedComponents />
    </StiggProvider>
  );
}

In some cases the customerId is not available when you render the StiggProvider component so it's more convenient to use the setCustomerId function directly from the Stigg JS SDK:

import { useStiggContext } from '@stigg/react-sdk';

export function App() { 
  const { stigg } = useStiggContext();
  
  useEffect(() => {
    stigg.setCustomerId(user.id);
  }, [stigg]);
}

Rendering widgets


Custom hooks

The React SDK provides hooks that give you access to the Stigg object, entitlement checks, and helper methods for fetching data:


useStiggContext

Use the useStiggContext React hook to access Stigg's JavaScript client easily from every component:

import React from 'react';  
import { useStiggContext } from '@stigg/react-sdk';

function App() {  
  const { stigg } = useStiggContext();

  useEffect(() => {  
    // Use stigg Javascript client function  
    stigg.getBooleanEntitlement(...)  
  })  
}

πŸ“˜

This hook will throw an error in case the Stigg context doesn't exists, it's possible to change that behavior by passing optional=true to the hook: const { stigg } = useStiggContext({ optional: true });

useBooleanEntitlement

The useBooleanEntitlement allows checking access for boolean entitlement:

import { useBooleanEntitlement, BooleanEntitlementFallback } from '@stigg/react-sdk';

const ENTITLEMENT_FALLBACK: BooleanEntitlementFallback = {
  hasAccess: true,
};

function App() {  
  const entitlement = useBooleanEntitlement({ 
    featureId: 'feature-custom-domain',
    options: { fallback: ENTITLEMENT_FALLBACK }
  });

  if (!entitlement.hasAccess) {
    return null
  }

  return <div>Customer has access to custom domain</div>
}

useNumericEntitlement

The useNumericEntitlement allows checking access for numeric entitlement:

import { useNumericEntitlement, NumericEntitlementFallback } from '@stigg/react-sdk';

const ENTITLEMENT_FALLBACK: NumericEntitlementFallback = {
  hasAccess: true,
  value: 100
};

function App() {  
  const entitlement = useNumericEntitlement({ 
    featureId: 'feature-max-file-size',
    options: { fallback: ENTITLEMENT_FALLBACK }
  });

  if (!entitlement.hasAccess) {
    return null
  }

  return <div>Customer has access to file size of {entitlement.value}GB</div>
}

useMeteredEntitlement

The useMeteredEntitlement allows checking access for metered entitlement:

import { useMeteredEntitlement, MeteredEntitlementFallback } from '@stigg/react-sdk';

const ENTITLEMENT_FALLBACK: MeteredEntitlementFallback = {
  hasAccess: true,
	isUnlimited: true,
};

function App() {  
  const entitlement = useMeteredEntitlement({ 
    featureId: 'feature-active-users',
    options: { 
      requestedUsage: 1,
      fallback: ENTITLEMENT_FALLBACK 
    }
  });

  if (!entitlement.hasAccess) {
    return null
  }

  return <div>Active users: {entitlement.currentUsage} / {entitlement.usageLimit}</div>
}

useActiveSubscriptions

The useActiveSubscriptions return the active subscriptions list:

import { useActiveSubscriptions } from '@stigg/react-sdk';

function App() {  
  const { activeSubscriptions, isLoaded } = useActiveSubscriptions();

  if (!isLoaded) {
    // Handle loading state
    return null
  }

  return (
    <div>You have {activeSubscriptions.length} active subscriptions</div>
  )
}

useCustomerPortal

The useCustomerPortal return the customer portal object:

import { useCustomerPortal } from '@stigg/react-sdk';

function App() {  
  const { customerPortal, isLoaded } = useCustomerPortal();

  if (!isLoaded) {
    // Handle loading state
    return null
  }

  return (
    <div>You have {customerPortal.subscriptions} subscriptions</div>
  )
}

usePaywall

The usePaywall return the paywall object:

import { usePaywall } from '@stigg/react-sdk';

function App() {  
  const { paywall, isLoaded } = usePaywall();

  if (!isLoaded) {
    // Handle loading state
    return null
  }

  return (
    <div>You can subscribe to the following plan: {paywall.plans}</div>
  )
}

Entitlement guard components

Entitlement guard components are useful in the cases where you need to wrap some part of the UI with an entitlement check and show a component in case the customer has no access to the feature:

BooleanEntitlementGuard

import { BooleanEntitlementGuard } from '@stigg/react-sdk';

function App() {  
  return (
    <BooleanEntitlementGuard 
      featureId="feature-custom-domain"
      noAccessComponent={<NoCustomDomain />}
      options={{ fallback: { hasAccess: true } }}>
      <CustomDomainSetup />
    </BooleanEntitlementGuard>
  )
}

NumericEntitlementGuard

import { NumericEntitlementGuard } from '@stigg/react-sdk';

function App() {  
  return (
    <NumericEntitlementGuard 
      featureId="feature-max-file-size"
      noAccessComponent={<NoFileUpload />}
      options={{ fallback: { hasAccess: true, value: 100 } }}>
      <FileUpload />
    </NumericEntitlementGuard>
  )
}

MeteredEntitlementGuard

import { MeteredEntitlementGuard } from '@stigg/react-sdk';

function App() {  
  return (
    <MeteredEntitlementGuard 
      featureId="feature-active-users"
      noAccessComponent={<NoAccess />}
      options={{ fallback: { hasAccess: true, isUnlimited: true } }}>
      <MainApp />
    </MeteredEntitlementGuard>
  )
}

Customization options

The widgets that are included in this package include a default theme, which can be customized to match the appearance of your application.

Global theming

You can pass customization options such as theming and locale to StiggProvider component. Doing so will affect all Stigg widgets that are descendent to the provider.

import React from 'react';  
import ReactDOM from 'react-dom';  
import { StiggProvider } from '@stigg/react-sdk';  
import App from './App';

// Example of the options that are available for the theme  
const theme = {  
  palette: {  
    primary: '#FFA500',  
    backgroundPaper: '#fcfbf8',  
    backgroundHighlight: '#FFF3E0',  
    outlinedHoverBackground: '#FFE0B2',
    text: {
      primary: '#333bf8',
      secondary: '#fcf222',
      disabled: '#fcf111',
    },
  },  
  layout: {  
    planMinWidth: '250px',  
    planMaxWidth: '250px',  
    ctaAlignment: 'center',  
    headerAlignment: 'center',  
    descriptionAlignment: 'center',  
  },  
  typography: {
    fontFamily: 'custom-font, DM Sans, sans-serif',
    h1: {
      fontSize: '32px',
      fontWeight: 'bold',
    },
    h2: {
      fontSize: '24px',
      fontWeight: 'normal',
    },
    h3: {
      fontSize: '16px',
      fontWeight: 'normal',
    },
    body: {
      fontSize: '14px',
      fontWeight: 'normal',
    },
  }
};

ReactDOM.render(  
  <StiggProvider apiKey="YOUR_CLIENT_API_KEY" theme={theme} locale="de-DE">  
    <App />  
  </StiggProvider>,  
  document.getElementById('app'),  
);

πŸ“˜

You can find more theming options here


Widget-specific customization

Each widget can be customized separately via the no-code widget designer in the Stigg app or using code.

Widget-specific customization capabilities can be found under the dedicated page of each widget.


Refreshing the cache

Stigg's SDK refreshes its cache of customer entitlements and usage data upon initialization (for example: when a page is refreshed), as well as periodically every 30 seconds.

After performing an operation on the backend that can modify the customer entitlements or the usage of a feature (for example: updating subscriptions or reporting usage), it's useful to immediately refresh the cache.

To do so, call the below method:

import { useStiggContext } from '@stigg/react-sdk';

function App() {
  const { stigg, refreshData } = useStiggContext();
  
  const addSeats = async () => {
    // Api call which modify customer entitlements (e.g. add seats or report usage)
    await api.addSeats();
    await refreshData();
  }
}

Offline mode

During local development or testing, you might want to avoid making network requests to the Stigg API.
To do this, you can run the React SDK in offline mode by enabling the offline option. When enabled, API key validation will always succeed, regardless of the key provided.

import { StiggProvider } from '@stigg/react-sdk';

export function App() {    
  return (
    <StiggProvider apiKey="<STIGG_CLIENT_API_KEY>" customerId={user.id} offline>
      <NestedComponents />
    </StiggProvider>
  );
}

In offline mode, the React SDK respects the global fallback strategy, and entitlement evaluations are limited to the values defined as fallback entitlements.

import { StiggProvider } from '@stigg/react-sdk';

export function App() {    
  return (
    <StiggProvider 
      apiKey="<STIGG_CLIENT_API_KEY>" 
      customerId={user.id} 
      offline
      entitlementsFallback={{
        'feature-number-of-seats': {
          hasAccess: true,
        },
        'feature-templates': {
          hasAccess: true,
          usageLimit: 10
        }
    }}>
      <NestedComponents />
    </StiggProvider>
  );
}

Full SDK reference

SDK changelog

Migration from older SDK versions to v3.x

  • Removed CSS class names (For an updated list of CSS class names check here)
    • stigg-overview-subscriptions-list-layout
    • stigg-overview-subscriptions-list
    • stigg-billing-information-layout
    • stigg-billing-information-title
    • stigg-update-billing-button
  • Paywall textOverrides.price.paid paid text customization callback signature was changed:
    from:
    {
      price: {
        paid?: (planPrice: Price, plan: Plan, selectedBillingPeriod: BillingPeriod) => PlanPriceText;
      }
    }
    
    to:
    {
      price: {
        paid?: (priceData: {
          planPrices: Price[];
          paywallCalculatedPrice?: PaywallCalculatedPricePoint;
          plan: Plan;
          selectedBillingPeriod: BillingPeriod;
        }) => PlanPriceText;
      }
    }