# useSuperwall

Purpose [#purpose]

The `useSuperwall` hook is the core hook that provides access to the Superwall store and underlying SDK functionality. It's generally used internally by other more specific hooks like `useUser` and `usePlacement`, but can be used directly for advanced scenarios. It ensures that native event listeners are set up on first use.

Returned Values (Store State and Actions) [#returned-values-store-state-and-actions]

The hook returns an object representing the Superwall store. If a `selector` function is provided, it returns the selected slice of the store.

State [#state]

<TypeTable
  type="{
  isConfigured: {
    type: &#x22;boolean&#x22;,
    description: &#x22;True if the SDK has been configured with an API key.&#x22;,
  },
  isLoading: {
    type: &#x22;boolean&#x22;,
    description: &#x22;True while the SDK is configuring or fetching data.&#x22;,
  },
  listenersInitialized: {
    type: &#x22;boolean&#x22;,
    description: &#x22;True if native event listeners have been initialized.&#x22;,
  },
  configurationError: {
    type: &#x22;string | null&#x22;,
    description: &#x22;Error message if configuration failed.&#x22;,
  },
  user: {
    type: &#x22;UserAttributes | null&#x22;,
    description: &#x22;Current user attributes. Null after reset; undefined before initial load.&#x22;,
  },
  subscriptionStatus: {
    type: &#x22;SubscriptionStatus&#x22;,
    description: &#x22;Current subscription status for the user.&#x22;,
  },
}"
/>

Actions (Functions) [#actions-functions]

<TypeTable
  type="{
  configure: {
    type: &#x22;(apiKey: string, options?: PartialSuperwallOptions) => Promise<void>&#x22;,
    description: &#x22;Initializes the SDK with your API key and optional configuration. Android only: set options.passIdentifiersToPlayStore to send raw appUserId to Google Play.&#x22;,
  },
  identify: {
    type: &#x22;(userId: string, options?: IdentifyOptions) => Promise<void>&#x22;,
    description: &#x22;Identifies the user with the given userId.&#x22;,
  },
  reset: {
    type: &#x22;() => Promise<void>&#x22;,
    description: &#x22;Resets the user's identity and clears user-specific data.&#x22;,
  },
  registerPlacement: {
    type: &#x22;(placement: string, params?: Record<string, any>, handlerId?: string | null) => Promise<void>&#x22;,
    description: &#x22;Registers a placement and optionally triggers a paywall.&#x22;,
  },
  getPresentationResult: {
    type: &#x22;(placement: string, params?: Record<string, any>) => Promise<PresentationResult>&#x22;,
    description: &#x22;Gets the presentation result for a placement without presenting.&#x22;,
  },
  restorePurchases: {
    type: &#x22;() => Promise<RestorationResultResponse>&#x22;,
    description: &#x22;Programmatically restores purchases and returns whether the restore succeeded or failed.&#x22;,
  },
  dismiss: {
    type: &#x22;() => Promise<void>&#x22;,
    description: &#x22;Dismisses any currently presented paywall.&#x22;,
  },
  preloadAllPaywalls: {
    type: &#x22;() => Promise<void>&#x22;,
    description: &#x22;Preloads all paywalls configured in the dashboard.&#x22;,
  },
  preloadPaywalls: {
    type: &#x22;(placements: string[]) => Promise<void>&#x22;,
    description: &#x22;Preloads paywalls for the specified placements.&#x22;,
  },
  setUserAttributes: {
    type: &#x22;(attrs: Record<string, any | null>) => Promise<void>&#x22;,
    description: &#x22;Sets custom attributes for the current user. Attribute values can be null.&#x22;,
  },
  getUserAttributes: {
    type: &#x22;() => Promise<Record<string, any>>&#x22;,
    description: &#x22;Retrieves the current user's attributes.&#x22;,
  },
  setLogLevel: {
    type: &#x22;(level: string) => Promise<void>&#x22;,
    description: &#x22;Sets the SDK log level (debug, info, warn, error, none).&#x22;,
  },
  setIntegrationAttributes: {
    type: &#x22;(attributes: IntegrationAttributes) => Promise<void>&#x22;,
    description: &#x22;Sets third-party integration identifiers, including `appstackId` for Appstack.&#x22;,
  },
  getIntegrationAttributes: {
    type: &#x22;() => Promise<Record<string, string>>&#x22;,
    description: &#x22;Returns currently set integration attributes.&#x22;,
  },
  setSubscriptionStatus: {
    type: &#x22;(status: SubscriptionStatus) => Promise<void>&#x22;,
    description: &#x22;Manually sets the user's subscription status.&#x22;,
  },
  getDeviceAttributes: {
    type: &#x22;() => Promise<Record<string, any>>&#x22;,
    description: &#x22;Returns device attributes from the native SDK.&#x22;,
  },
  getEntitlements: {
    type: &#x22;() => Promise<EntitlementsInfo>&#x22;,
    description: &#x22;Fetches the user's entitlement snapshot, including active and inactive entitlements, plus all known entitlements when exposed by the native bridge.&#x22;,
  },
}"
/>

Selector (Optional Parameter) [#selector-optional-parameter]

<TypeTable
  type="{
  selector: {
    type: &#x22;(state: SuperwallStore) => T&#x22;,
    description: &#x22;Selects a slice of store state for shallow-equality rendering.&#x22;,
  },
}"
/>

UserAttributes [#userattributes]

<TypeTable
  type="{
  aliasId: {
    type: &#x22;string&#x22;,
    description: &#x22;Alias ID for the user.&#x22;,
  },
  appUserId: {
    type: &#x22;string&#x22;,
    description: &#x22;Application-specific user ID.&#x22;,
  },
  applicationInstalledAt: {
    type: &#x22;string&#x22;,
    description: &#x22;ISO date string for when the app was installed.&#x22;,
  },
  seed: {
    type: &#x22;number&#x22;,
    description: &#x22;Seed used for experiment assignment.&#x22;,
  },
  &#x22;[key: string]&#x22;: {
    type: &#x22;any | null&#x22;,
    description: &#x22;Other custom user attributes. Values may be null.&#x22;,
  },
}"
/>

SubscriptionStatus [#subscriptionstatus]

<TypeTable
  type="{
  status: {
    type: &#x22;\&#x22;UNKNOWN\&#x22; | \&#x22;INACTIVE\&#x22; | \&#x22;ACTIVE\&#x22;&#x22;,
    description: &#x22;Current subscription status value.&#x22;,
    required: true,
  },
  entitlements: {
    type: &#x22;Entitlement[]?&#x22;,
    description: &#x22;Only present when status is \&#x22;ACTIVE\&#x22;.&#x22;,
  },
}"
/>

EntitlementsInfo [#entitlementsinfo]

<TypeTable
  type="{
  all: {
    type: &#x22;Entitlement[]?&#x22;,
    description: &#x22;All entitlements known for the user. Present when the native bridge exposes the full entitlement set.&#x22;,
  },
  active: {
    type: &#x22;Entitlement[]&#x22;,
    description: &#x22;Entitlements that are currently active.&#x22;,
    required: true,
  },
  inactive: {
    type: &#x22;Entitlement[]&#x22;,
    description: &#x22;Entitlements that are known but not currently active.&#x22;,
    required: true,
  },
}"
/>

RestorationResultResponse [#restorationresultresponse]

<TypeTable
  type="{
  result: {
    type: '&#x22;restored&#x22; | &#x22;failed&#x22;',
    description: &#x22;Outcome of the restore attempt.&#x22;,
    required: true,
  },
  errorMessage: {
    type: &#x22;string | null&#x22;,
    description: &#x22;Error message when `result` is `failed`.&#x22;,
  },
}"
/>

Example [#example]

(Direct Usage - Advanced)

```tsx
import { useSuperwall } from 'expo-superwall';

function MyAdvancedComponent() {
  const { isConfigured, configure, setUserAttributes } = useSuperwall();

  if (!isConfigured) {
    return <Text>SDK not configured yet.</Text>;
  }

  const handleSetCustomAttribute = () => {
    setUserAttributes({ myCustomFlag: true });
  };

  return <Button title="Set Custom Flag" onPress={handleSetCustomAttribute} />;
}
```

Example: Configure with Android identifiers [#example-configure-with-android-identifiers]

```tsx
import { Platform } from "react-native"
import Superwall from "expo-superwall/compat"

async function configureSuperwall() {
  await Superwall.configure({
    apiKey: Platform.OS === "ios" ? IOS_KEY : ANDROID_KEY,
    options: Platform.OS === "android"
      ? { passIdentifiersToPlayStore: true }
      : undefined,
  })
}
```