# React

Examples of common tiun SDK patterns in React. Each section is standalone — use what applies to your integration.

***

## Initialize

Initialize the SDK inside a top-level `useEffect` with an empty dependency array. Return `tiun.destroy()` as the cleanup so dev-mode StrictMode (which double-invokes effects) tears down cleanly.

```tsx
import { tiun } from '@tiun/sdk';
import { useEffect } from 'react';

function App() {
  useEffect(() => {
    tiun.init({
      snippetId: 'YOUR_SNIPPET_ID',
      language: 'en', // 'en' | 'de' | 'fr'
    });
    return () => tiun.destroy();
  }, []);

  return <>{/* your app */}</>;
}
```

See [Lifecycle and `destroy()`](/sdk/getting-started/initialization.md#lifecycle-and-destroy) for when teardown is and isn't needed in other hosts.

***

## Checkout

Trigger checkout on a button click. Pass the product ID from your dashboard.

```tsx
import { tiun } from '@tiun/sdk';

function PricingPage() {
  return (
    <div>
      <button onClick={() => tiun.checkout({ productId: 'p-live-light' })}>
        Light — EUR 19/mo
      </button>
      <button onClick={() => tiun.checkout({ productId: 'p-live-pro' })}>
        Pro — EUR 199/mo
      </button>
    </div>
  );
}
```

***

## Listen for user changes

Track authentication and access state with `userChange`. Store it in React state so your components re-render when the user changes.

```tsx
import { tiun } from '@tiun/sdk';
import { useEffect, useState } from 'react';

function App() {
  const [user, setUser] = useState(tiun.getUser());

  useEffect(() => {
    tiun.init({ snippetId: 'YOUR_SNIPPET_ID', language: 'en' });

    tiun.on('userChange', (data) => {
      setUser({ isAuthenticated: data.isAuthenticated, user: data.user });
    });

    return () => tiun.destroy();
  }, []);

  return <>{/* use user.isAuthenticated and user.user */}</>;
}
```

***

## Gate content

Show or hide content based on `productAccess`.

```tsx
function PremiumSection({ user }) {
  if (!user.isAuthenticated) {
    return <p>Please log in or subscribe.</p>;
  }

  const hasPro = user.user?.productAccess.includes('p-live-pro');

  if (hasPro) {
    return <div>{/* Pro content */}</div>;
  }

  return (
    <button onClick={() => tiun.checkout({ productId: 'p-live-pro' })}>
      Upgrade to Pro
    </button>
  );
}
```

***

## Login and logout

Add authentication buttons to your navigation.

```tsx
import { tiun } from '@tiun/sdk';

function Nav({ user }) {
  if (user.isAuthenticated) {
    return (
      <nav>
        <span>{user.user.email}</span>
        <button onClick={() => tiun.logout()}>Log out</button>
      </nav>
    );
  }

  return (
    <nav>
      <button onClick={() => tiun.login()}>Log in</button>
    </nav>
  );
}
```

***

## Paywall events (time-based)

For time-based billing, use `paywallShow` and `paywallHide` to control access.

```tsx
import { tiun } from '@tiun/sdk';
import { useEffect, useState } from 'react';

function PaywallGate({ children }) {
  const [hasAccess, setHasAccess] = useState(false);

  useEffect(() => {
    tiun.on('paywallHide', () => setHasAccess(true));
    tiun.on('paywallShow', () => setHasAccess(false));
  }, []);

  if (!hasAccess) {
    return (
      <div>
        <h2>Premium content</h2>
        <button onClick={() => tiun.start()}>
          Get access
        </button>
      </div>
    );
  }

  return <>{children}</>;
}
```

***

## Content management (time-based)

Call `setContent()` on route changes to keep billing accurate.

```tsx
import { tiun } from '@tiun/sdk';
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function ContentTracker() {
  const location = useLocation();

  useEffect(() => {
    const isPaid = isPaidContent(location.pathname);
    tiun.setContent({
      type: isPaid ? 'active' : 'inactive',
      contentId: location.pathname
    });
  }, [location.pathname]);

  return null;
}
```


---

# Agent Instructions: 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:

```
GET https://docs.tiun.io/sdk/examples/react.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
