Skip to main content
Checks whether the tenant’s active plan includes a given feature key. Supports multi-product orgs via a productSlug option and an optional remote API check.

Usage

import { useFeatureAccess } from 'crovver-react';

function ExportButton() {
  const { hasAccess, isLoading, redirectToUpgrade } = useFeatureAccess('data_export');

  if (isLoading) return null;

  return hasAccess
    ? <button onClick={exportData}>Export CSV</button>
    : <button onClick={redirectToUpgrade}>Upgrade to Export</button>;
}

Parameters

ParamTypeDefaultDescription
featurestringFeature key to check. Optional when productSlug is provided — omitting it performs a subscription-existence check.
opts.checkRemotebooleanfalseCheck via API instead of local plan data. Required when using productSlug.
opts.productSlugstringScope the check to a specific product. Overrides the provider-level productSlug for this call.

Return Value

{
  hasAccess: boolean;     // true if the plan includes this feature
  canAccess: boolean;     // alias for hasAccess
  isLoading: boolean;
  error: Error | null;
  redirectToUpgrade: () => void;
  refresh: () => Promise<void>;
}

How Access Is Determined

By default this is a local check — no API call is made. The subscription data fetched by CrovverProvider on mount is used:
  1. No active subscription → hasAccess: false
  2. Feature not in plan.featureshasAccess: false
  3. plan.features[featureKey] === truehasAccess: true
When checkRemote: true, the hook calls POST /api/public/can-access on every render cycle change, which supports productSlug scoping.

Examples

Disable a button instead of hiding it

const { hasAccess } = useFeatureAccess('bulk_operations');

<button disabled={!hasAccess} title={!hasAccess ? 'Upgrade to unlock' : undefined}>
  Bulk Delete
</button>

Multi-product: scope to a specific product

// Feature gate scoped to a product (requires remote check)
const { hasAccess } = useFeatureAccess('job_posting', {
  checkRemote: true,
  productSlug: 'product-a',
});

Subscription-existence check

// Does this tenant have any active subscription for product-a?
const { hasAccess: hasProductA } = useFeatureAccess(undefined, {
  checkRemote: true,
  productSlug: 'product-a',
});

Check multiple features

const analytics = useFeatureAccess('advanced_analytics');
const exports   = useFeatureAccess('data_export');
const api       = useFeatureAccess('api_access');