npm package: @intentai/react
Description: Official React SDK for Intent AI - AI-powered feedback collection widget with frustration detection and proactive help
Author: Intent AI
Latest version: 2.3.0

# @intentai/react

Official React SDK for [Intent AI](https://intent-ai.com) - AI-powered feedback collection widget.

## Installation

```bash
npm install @intentai/react
# or
yarn add @intentai/react
# or
pnpm add @intentai/react
```

## Quick Start

### 1. Get your Public Key

Get your public key (`pk_live_*` or `pk_test_*`) from the [Intent AI Dashboard](https://app.intent-ai.com/dashboard/settings).

### 2. Add the Provider

Wrap your app with `IntentAIProvider`:

```tsx
// app/layout.tsx (Next.js App Router)
import { IntentAIProvider } from '@intentai/react';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <IntentAIProvider apiKey="pk_live_xxxxx">
          {children}
        </IntentAIProvider>
      </body>
    </html>
  );
}
```

That's it! The feedback widget will appear in the bottom-right corner.

## Environment Variables

The SDK automatically detects your API key from environment variables:

```env
# Next.js
NEXT_PUBLIC_INTENT_AI_KEY=pk_live_xxxxx

# Create React App
REACT_APP_INTENT_AI_KEY=pk_live_xxxxx

# Vite
VITE_INTENT_AI_KEY=pk_live_xxxxx
```

With environment variables set, you can omit the `apiKey` prop:

```tsx
<IntentAIProvider>
  {children}
</IntentAIProvider>
```

## Usage

### Basic Setup

```tsx
import { IntentAIProvider } from '@intentai/react';

function App() {
  return (
    <IntentAIProvider
      apiKey="pk_live_xxxxx"
      position="bottom-right"
      theme="auto"
    >
      <YourApp />
    </IntentAIProvider>
  );
}
```

### Custom Feedback Button

```tsx
import { IntentAIProvider, FeedbackButton } from '@intentai/react';

function App() {
  return (
    <IntentAIProvider apiKey="pk_live_xxxxx" autoShow={false}>
      <FeedbackButton className="btn btn-primary">
        Send Feedback
      </FeedbackButton>
    </IntentAIProvider>
  );
}
```

### Using the Hook

```tsx
import { useIntentAI } from '@intentai/react';

function MyComponent() {
  const { open, close, isReady, error } = useIntentAI();

  if (error) {
    return <div>Failed to load feedback widget</div>;
  }

  return (
    <button onClick={() => open()} disabled={!isReady}>
      Give Feedback
    </button>
  );
}
```

### Identify Users

Using the `useIdentify` hook (recommended):

```tsx
import { useIdentify } from '@intentai/react';

function AuthenticatedApp({ user }) {
  // Automatically identifies user when ready
  useIdentify(user ? {
    id: user.id,
    email: user.email,
    name: user.name,
    plan: user.subscription.plan,
  } : null);

  return <YourApp />;
}
```

Using the `IdentifyUser` component:

```tsx
import { IntentAIProvider, IdentifyUser } from '@intentai/react';

function App({ user }) {
  return (
    <IntentAIProvider apiKey="pk_live_xxxxx">
      <IdentifyUser user={{
        id: user.id,
        email: user.email,
        name: user.name
      }}>
        <YourApp />
      </IdentifyUser>
    </IntentAIProvider>
  );
}
```

Or using the hook directly:

```tsx
import { useIntentAI } from '@intentai/react';

function AuthenticatedApp({ user }) {
  const { identify, isReady } = useIntentAI();

  useEffect(() => {
    if (isReady && user) {
      identify({
        id: user.id,
        email: user.email,
        name: user.name,
        plan: user.subscription.plan, // Custom properties
      });
    }
  }, [isReady, user]);

  return <YourApp />;
}
```

### Add Metadata

```tsx
import { SetMetadata } from '@intentai/react';

function PricingPage() {
  return (
    <SetMetadata metadata={{ page: 'pricing', feature: 'comparison' }}>
      <PricingContent />
    </SetMetadata>
  );
}
```

Or using the hook:

```tsx
const { setMetadata } = useIntentAI();

useEffect(() => {
  setMetadata({
    page: window.location.pathname,
    viewport: `${window.innerWidth}x${window.innerHeight}`
  });
}, []);
```

### Track Events

Using the `TrackEvent` component:

```tsx
import { TrackEvent } from '@intentai/react';

function CheckoutPage() {
  return (
    <TrackEvent event="checkout_viewed" properties={{ items: 3 }}>
      <CheckoutContent />
    </TrackEvent>
  );
}
```

Using the hook:

```tsx
const { track } = useIntentAI();

function handlePurchase(item) {
  track('purchase', {
    itemId: item.id,
    price: item.price
  });
}
```

### Custom Trigger with FeedbackTrigger

```tsx
import { FeedbackTrigger } from '@intentai/react';

function App() {
  return (
    <FeedbackTrigger>
      {({ open, isReady }) => (
        <MyCustomButton onClick={() => open()} disabled={!isReady}>
          Feedback
        </MyCustomButton>
      )}
    </FeedbackTrigger>
  );
}
```

### Pre-fill Feedback

```tsx
const { open } = useIntentAI();

// Open with pre-selected type and prefilled text
open({
  type: 'bug',
  prefill: { text: 'I found an issue with...' },
  metadata: { page: 'checkout' }
});
```

## Configuration

### IntentAIProvider Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `apiKey` | `string` | - | Your Intent AI public key (or use env vars) |
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `'bottom-right'` | Widget position |
| `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Color theme |
| `primaryColor` | `string` | `'#6366f1'` | Primary brand color (hex) |
| `autoShow` | `boolean` | `true` | Show widget button automatically |
| `user` | `UserIdentity` | - | Initial user identification |
| `metadata` | `Record<string, unknown>` | - | Custom metadata |
| `onReady` | `() => void` | - | Called when widget is ready |
| `onOpen` | `() => void` | - | Called when widget opens |
| `onClose` | `() => void` | - | Called when widget closes |
| `onSubmit` | `(data: FeedbackData) => void` | - | Called on feedback submission |
| `onError` | `(error: Error) => void` | - | Called on errors |

### useIntentAI Hook

```tsx
const {
  isReady,    // boolean - Widget loaded and ready
  error,      // Error | null - Error if widget failed to load
  open,       // (options?: OpenOptions) => void - Open the widget
  close,      // () => void - Close the widget
  identify,   // (user: UserIdentity) => void - Identify user
  setMetadata,// (data: Record<string, unknown>) => void - Set metadata
  track,      // (event: string, properties?: Record<string, unknown>) => void - Track event
} = useIntentAI();
```

### useIdentify Hook

```tsx
// Automatically identifies user when widget is ready
useIdentify({
  id: 'user_123',
  email: 'user@example.com',
  name: 'John Doe',
  plan: 'pro',
  company: 'Acme Inc',
});

// Pass null to skip identification
useIdentify(user ? { id: user.id, email: user.email } : null);
```

### OpenOptions

```tsx
interface OpenOptions {
  type?: 'bug' | 'feature' | 'question' | 'praise' | 'other';
  prefill?: { text?: string };
  metadata?: Record<string, unknown>;
}
```

### UserIdentity

```tsx
interface UserIdentity {
  id: string;           // Required
  email?: string;
  name?: string;
  avatar?: string;
  plan?: string;
  company?: string;
  [key: string]: string | number | boolean | undefined; // Custom properties
}
```

## Next.js App Router

The SDK is fully compatible with Next.js App Router and Server Components:

```tsx
// app/providers.tsx
'use client';

import { IntentAIProvider } from '@intentai/react';

export function Providers({ children }) {
  return (
    <IntentAIProvider>
      {children}
    </IntentAIProvider>
  );
}

// app/layout.tsx
import { Providers } from './providers';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}
```

## TypeScript

Full TypeScript support with exported types:

```tsx
import type {
  UserIdentity,
  IntentAIConfig,
  FeedbackData,
  OpenOptions,
  FeedbackType,
} from '@intentai/react';

const user: UserIdentity = {
  id: '123',
  email: 'user@example.com',
  name: 'John Doe',
};
```

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)

## License

MIT © [Intent AI](https://intent-ai.com)