TypeScript SDK
React Components

React Components

The HiveForge SDK includes optional React components and hooks for building entitlement-aware UIs. These are tree-shaken out if React is not used.

React is an optional peer dependency. Install it separately if not already in your project: npm install react.

Provider Setup

Wrap your application with HiveForgeProvider or EntitlementWrapper to make HiveForge state available to all child components.

HiveForgeProvider

The base provider that supplies HiveForge context. You manage initialization and state display yourself.

import { HiveForgeClient, HiveForgeProvider } from '@producthacker/hiveforge-sdk';
 
const hiveforge = new HiveForgeClient({
  deploymentId: process.env.NEXT_PUBLIC_HIVEFORGE_DEPLOYMENT_ID!,
  deploymentSecret: process.env.HIVEFORGE_DEPLOYMENT_SECRET!,
});
 
function App() {
  return (
    <HiveForgeProvider client={hiveforge}>
      <YourApp />
    </HiveForgeProvider>
  );
}

Props:

PropTypeRequiredDescription
clientHiveForgeClientYesAn initialized (or to-be-initialized) client instance
childrenReactNodeYesChild components

The provider automatically calls initialize() if the client has not been initialized yet, and subscribes to entitlements:updated and entitlements:error events.

EntitlementWrapper

A higher-level wrapper that includes HiveForgeProvider and automatically handles suspended and grace period states with built-in UI.

import { HiveForgeClient, EntitlementWrapper } from '@producthacker/hiveforge-sdk';
 
const hiveforge = new HiveForgeClient({
  deploymentId: process.env.NEXT_PUBLIC_HIVEFORGE_DEPLOYMENT_ID!,
  deploymentSecret: process.env.HIVEFORGE_DEPLOYMENT_SECRET!,
});
 
function App() {
  return (
    <EntitlementWrapper client={hiveforge} upgradeUrl="/pricing">
      <YourApp />
    </EntitlementWrapper>
  );
}

Props:

PropTypeRequiredDescription
clientHiveForgeClientYesClient instance
childrenReactNodeYesChild components
upgradeUrlstringNoURL for the upgrade/renew subscription link

Built-in behavior:

  • Shows a loading state while entitlements are being fetched
  • Renders SuspendedPage if the subscription status is suspended
  • Shows GracePeriodBanner above your app content during grace_period status
  • Renders your app normally for active, trialing, and other statuses

Hooks

All hooks must be used inside a HiveForgeProvider or EntitlementWrapper.


useHiveForge()

Access the full HiveForge context including the client, entitlements, loading state, and refresh function.

import { useHiveForge } from '@producthacker/hiveforge-sdk';
 
function Dashboard() {
  const { client, entitlements, isLoading, error, refresh } = useHiveForge();
 
  if (isLoading) return <div>Loading entitlements...</div>;
  if (error) return <div>Error: {error.message}</div>;
 
  return (
    <div>
      <p>Tier: {entitlements?.tier}</p>
      <p>Status: {entitlements?.status}</p>
      <button onClick={refresh}>Refresh Entitlements</button>
    </div>
  );
}

Returns (HiveForgeContextValue):

FieldTypeDescription
clientHiveForgeClientThe SDK client instance
entitlementsEntitlements | nullCurrent entitlements (null while loading)
isLoadingbooleanWhether entitlements are being fetched
errorError | nullMost recent error, if any
refresh() => Promise<void>Manually refresh entitlements

useEntitlements()

Get the current entitlements object directly.

import { useEntitlements } from '@producthacker/hiveforge-sdk';
 
function PlanInfo() {
  const entitlements = useEntitlements();
 
  if (!entitlements) return null;
 
  return (
    <div>
      <p>Tier: {entitlements.tier}</p>
      <p>AI limit: {entitlements.features.ai_monthly_limit ?? 'Unlimited'}</p>
    </div>
  );
}

Returns: Entitlements | null


useFeature(feature)

Check if a specific feature flag is enabled. Returns false while entitlements are loading.

import { useFeature } from '@producthacker/hiveforge-sdk';
 
function AIButton() {
  const aiEnabled = useFeature('ai_enabled');
 
  if (!aiEnabled) {
    return <button disabled>AI (Upgrade Required)</button>;
  }
 
  return <button onClick={handleAI}>Ask AI</button>;
}

Parameters:

NameTypeDescription
featurekeyof FeatureFlagsFeature flag to check

Returns: boolean


useSubscriptionStatus()

Get the current subscription status string.

import { useSubscriptionStatus } from '@producthacker/hiveforge-sdk';
 
function StatusBadge() {
  const status = useSubscriptionStatus();
 
  const colors: Record<string, string> = {
    active: 'green',
    trialing: 'blue',
    past_due: 'orange',
    grace_period: 'yellow',
    suspended: 'red',
    canceled: 'gray',
  };
 
  return (
    <span style={{ color: colors[status] }}>
      {status.replace('_', ' ').toUpperCase()}
    </span>
  );
}

Returns: SubscriptionStatus -- one of 'active', 'trialing', 'past_due', 'grace_period', 'suspended', 'canceled'.


useTier()

Get the current subscription tier.

import { useTier } from '@producthacker/hiveforge-sdk';
 
function TierDisplay() {
  const tier = useTier();
 
  return <span>Current plan: {tier}</span>;
}

Returns: string -- e.g., 'sandbox', 'trial', 'launch', 'growth', 'enterprise'.


useMessage()

Get the user-facing message from entitlements (e.g., trial expiration warnings).

import { useMessage } from '@producthacker/hiveforge-sdk';
 
function TrialBanner() {
  const message = useMessage();
 
  if (!message) return null;
 
  return (
    <div style={{ background: '#FEF3C7', padding: '0.75rem', textAlign: 'center' }}>
      {message}
    </div>
  );
}

Returns: string | null

Components


EntitlementGate

Conditionally render children based on whether a feature flag is enabled. Renders the fallback (or nothing) when the feature is disabled.

import { EntitlementGate } from '@producthacker/hiveforge-sdk';
 
function FeaturePage() {
  return (
    <div>
      <h1>Dashboard</h1>
 
      <EntitlementGate feature="ai_enabled" fallback={<UpgradePrompt feature="AI" />}>
        <AIAssistantPanel />
      </EntitlementGate>
 
      <EntitlementGate feature="billing_enabled">
        <BillingSection />
      </EntitlementGate>
 
      <EntitlementGate
        feature="white_label"
        fallback={<p>White labeling is available on Growth and Enterprise plans.</p>}
      >
        <WhiteLabelSettings />
      </EntitlementGate>
    </div>
  );
}
 
function UpgradePrompt({ feature }: { feature: string }) {
  return (
    <div style={{ padding: '2rem', textAlign: 'center', background: '#f5f5f5' }}>
      <p>{feature} is not available on your current plan.</p>
      <a href="/pricing">Upgrade to unlock {feature}</a>
    </div>
  );
}

Props:

PropTypeRequiredDefaultDescription
featurekeyof FeatureFlagsYes--Feature flag to check
fallbackReactNodeNonullWhat to render when feature is disabled
childrenReactNodeYes--What to render when feature is enabled

SuspendedPage

A full-page component displayed when the subscription is suspended. Used internally by EntitlementWrapper but can be used standalone.

import { SuspendedPage } from '@producthacker/hiveforge-sdk';
 
function CustomSuspendedHandler() {
  const status = useSubscriptionStatus();
 
  if (status === 'suspended') {
    return (
      <SuspendedPage
        message="Your subscription has expired. Renew to regain access."
        upgradeUrl="/pricing"
      />
    );
  }
 
  return <AppContent />;
}

Props:

PropTypeRequiredDefaultDescription
messagestringNoGeneric suspension messageCustom message to display
upgradeUrlstringNo--URL for the renewal button

GracePeriodBanner

A banner displayed at the top of the page during a grace period. Used internally by EntitlementWrapper but can be used standalone.

import { GracePeriodBanner, useHiveForge } from '@producthacker/hiveforge-sdk';
 
function AppLayout({ children }: { children: React.ReactNode }) {
  const { entitlements } = useHiveForge();
 
  return (
    <div>
      {entitlements?.status === 'grace_period' && (
        <GracePeriodBanner
          message={entitlements.message ?? undefined}
          upgradeUrl="/pricing"
        />
      )}
      <main>{children}</main>
    </div>
  );
}

Props:

PropTypeRequiredDefaultDescription
messagestringNoGeneric grace period messageCustom message to display
upgradeUrlstringNo--URL for the renewal button

Full Example: Next.js App

// app/providers.tsx
'use client';
 
import { HiveForgeClient, EntitlementWrapper } from '@producthacker/hiveforge-sdk';
import { useMemo } from 'react';
 
export function Providers({ children }: { children: React.ReactNode }) {
  const hiveforge = useMemo(() => new HiveForgeClient({
    deploymentId: process.env.NEXT_PUBLIC_HIVEFORGE_DEPLOYMENT_ID!,
    deploymentSecret: process.env.NEXT_PUBLIC_HIVEFORGE_DEPLOYMENT_SECRET!,
  }), []);
 
  return (
    <EntitlementWrapper client={hiveforge} upgradeUrl="/pricing">
      {children}
    </EntitlementWrapper>
  );
}
// app/layout.tsx
import { Providers } from './providers';
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}
// app/dashboard/page.tsx
'use client';
 
import {
  useHiveForge,
  useFeature,
  useTier,
  useMessage,
  EntitlementGate,
} from '@producthacker/hiveforge-sdk';
 
export default function DashboardPage() {
  const { isLoading, error } = useHiveForge();
  const tier = useTier();
  const message = useMessage();
  const aiEnabled = useFeature('ai_enabled');
 
  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
 
  return (
    <div>
      <h1>Dashboard</h1>
      <p>Plan: {tier}</p>
      {message && <p style={{ color: '#b45309' }}>{message}</p>}
 
      <EntitlementGate feature="ai_enabled" fallback={<p>Upgrade to use AI features.</p>}>
        <section>
          <h2>AI Assistant</h2>
          {/* AI-powered features here */}
        </section>
      </EntitlementGate>
    </div>
  );
}