> For the complete documentation index, see [llms.txt](https://docs.tiun.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tiun.io/sdk/react-native-sdk/examples.md).

# Examples

Common tiun patterns in a React Native app. Each section is standalone — use what applies to your integration.

These assume the SDK and its native dependencies are installed and your return deep link is registered. See [Installation](/sdk/react-native-sdk/installation.md) if not.

***

## Set up the provider

Keep the config and your product IDs in one module so screens, gating logic, and analytics all reference the same values.

```tsx
// tiun.ts
import type { TiunConfig } from '@tiun/react-native-sdk';

export const TIUN_CONFIG: TiunConfig = {
  snippetId: 'YOUR_SNIPPET_ID',
  returnUrl: 'myapp://tiun/return',
  language: 'en', // 'en' | 'de' | 'fr'
};

export const TIUN_PRODUCTS = {
  light: 'p-live-light',
  pro: 'p-live-pro',
} as const;
```

Wrap the app root in the provider:

```tsx
import { TiunProvider } from '@tiun/react-native-sdk';
import { TIUN_CONFIG } from './tiun';

export default function App() {
  return (
    <TiunProvider config={TIUN_CONFIG}>
      <RootNavigator />
    </TiunProvider>
  );
}
```

***

## Checkout

Call `checkout()` with the product ID from your dashboard. tiun opens the overlay and handles email, payment, and access in one flow.

```tsx
import { Button, View } from 'react-native';
import { useTiun } from '@tiun/react-native-sdk';
import { TIUN_PRODUCTS } from './tiun';

function PricingScreen() {
  const { checkout } = useTiun();

  return (
    <View>
      <Button
        title="Light — EUR 19/mo"
        onPress={() => checkout({ productId: TIUN_PRODUCTS.light })}
      />
      <Button
        title="Pro — EUR 199/mo"
        onPress={() => checkout({ productId: TIUN_PRODUCTS.pro })}
      />
    </View>
  );
}
```

***

## Track the user

`useTiun()` already re-renders your component when the user changes, so for most screens reading `user` directly is enough:

```tsx
import { Text } from 'react-native';
import { useTiun } from '@tiun/react-native-sdk';

function AccountBadge() {
  const { isAuthenticated, user } = useTiun();

  if (!isAuthenticated) return <Text>Not signed in</Text>;
  return <Text>{user?.email}</Text>;
}
```

Use `useTiunEvent('userChange')` when you need to *react* to the change — refetching data, resetting a screen, or mirroring the user into your own store:

```tsx
import { useState } from 'react';
import { useTiunEvent, type TiunUser } from '@tiun/react-native-sdk';

function AppShell() {
  const [user, setUser] = useState<TiunUser | null>(null);

  useTiunEvent('userChange', ({ user: nextUser }) => {
    setUser(nextUser);
  });

  // ...
}
```

`userChange` also fires once when the stored session is restored at launch, so this covers the initial state too.

***

## Gate content

Derive what the user can see from `productAccess`. Deriving a single "current tier" keeps the check in one place instead of scattering `includes()` calls through your screens.

```tsx
import { useTiun } from '@tiun/react-native-sdk';
import { TIUN_PRODUCTS } from './tiun';

type Tier = 'free' | 'light' | 'pro';

function useTier(): Tier {
  const { user } = useTiun();
  const access = user?.productAccess ?? [];

  if (access.includes(TIUN_PRODUCTS.pro)) return 'pro';
  if (access.includes(TIUN_PRODUCTS.light)) return 'light';
  return 'free';
}
```

Then gate on it:

```tsx
import { Button, Text, View } from 'react-native';
import { useTiun } from '@tiun/react-native-sdk';
import { TIUN_PRODUCTS } from './tiun';

function ArticleScreen({ article }: { article: Article }) {
  const tier = useTier();
  const { checkout } = useTiun();

  if (!canRead(article, tier)) {
    return (
      <View>
        <Text>This article is for Pro subscribers.</Text>
        <Button
          title="Upgrade to Pro"
          onPress={() => checkout({ productId: TIUN_PRODUCTS.pro })}
        />
      </View>
    );
  }

  return <ArticleBody article={article} />;
}
```

***

## Login and logout

Returning subscribers sign in without going through checkout again. Their `productAccess` comes back with the session.

```tsx
import { Button } from 'react-native';
import { useTiun } from '@tiun/react-native-sdk';

function AuthButton() {
  const { isAuthenticated, login, logout } = useTiun();

  return (
    <Button
      title={isAuthenticated ? 'Log out' : 'Log in'}
      onPress={() => (isAuthenticated ? logout() : login())}
    />
  );
}
```

***

## Verify on your server

Client-side gating controls what the app renders. If your backend serves the premium payload itself, verify the user there before responding.

```tsx
import { useTiun } from '@tiun/react-native-sdk';

function usePremiumFetch() {
  const { getUserVerificationToken } = useTiun();

  return async function fetchPremium(path: string) {
    const token = await getUserVerificationToken();
    if (!token) return null;

    const response = await fetch(`https://api.example.com${path}`, {
      headers: { Authorization: `Bearer ${token}` },
    });

    return response.ok ? response.json() : null;
  };
}
```

The backend half is the same as for the web SDK — see [verify authentication server-side](/guides/authentication/verify-server-side.md) and [verify subscriptions server-side](/guides/subscriptions/verify-server-side.md).

***

## Full example

A tiered app in one file: entitlements drive the current tier, the pricing screen opens checkout, and the tab bar handles auth.

```tsx
import { useMemo, useState } from 'react';
import { Button, SafeAreaView, Text, View } from 'react-native';
import {
  TiunProvider,
  useTiun,
  useTiunEvent,
  type TiunConfig,
  type TiunUser,
} from '@tiun/react-native-sdk';

const TIUN_CONFIG: TiunConfig = {
  snippetId: 'YOUR_SNIPPET_ID',
  returnUrl: 'myapp://tiun/return',
  language: 'en',
};

const TIUN_PRODUCTS = {
  light: 'p-live-light',
  pro: 'p-live-pro',
} as const;

type Tier = 'free' | 'light' | 'pro';

function tierFromUser(user: TiunUser | null): Tier {
  const access = user?.productAccess ?? [];
  if (access.includes(TIUN_PRODUCTS.pro)) return 'pro';
  if (access.includes(TIUN_PRODUCTS.light)) return 'light';
  return 'free';
}

function AppShell() {
  const { checkout, login, logout, isAuthenticated } = useTiun();
  const [user, setUser] = useState<TiunUser | null>(null);

  useTiunEvent('userChange', ({ user: nextUser }) => setUser(nextUser));

  const tier = useMemo(() => tierFromUser(user), [user]);

  return (
    <SafeAreaView>
      <Text>Current plan: {tier}</Text>

      {tier === 'free' && (
        <Button
          title="Subscribe to Light"
          onPress={() => checkout({ productId: TIUN_PRODUCTS.light })}
        />
      )}

      {tier !== 'pro' && (
        <Button
          title="Go Pro"
          onPress={() => checkout({ productId: TIUN_PRODUCTS.pro })}
        />
      )}

      <View>
        <Button
          title={isAuthenticated ? 'Log out' : 'Log in'}
          onPress={() => (isAuthenticated ? logout() : login())}
        />
      </View>
    </SafeAreaView>
  );
}

export default function App() {
  return (
    <TiunProvider config={TIUN_CONFIG}>
      <AppShell />
    </TiunProvider>
  );
}
```

***

For the full API, see [Hooks and events](/sdk/react-native-sdk/hooks.md). For an end-to-end walkthrough from dashboard to production, see [monetize in React Native](/guides/react-native/monetize-in-react-native.md) in Guides.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tiun.io/sdk/react-native-sdk/examples.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
