# React quickstart

Get an agent running in your React app in under 5 minutes.

## Prerequisites

- A React 18+ app (Next.js 13+, Vite, Remix, CRA, etc.)
- An agent published on `app.livelayer.studio` (you'll need its `agentId`)

## Step 1 — Install

```bash title="install.sh"
npm install @livelayer/react @livelayer/sdk
```

`@livelayer/sdk` is a peer dependency — install both. They release in lockstep.

## Step 2 — Render

```tsx title="app.tsx"
import { AvatarWidget } from "@livelayer/react";
import "@livelayer/react/styles.css";

export default function App() {
  return <!-- omitted: AvatarWidget -->;
}
```

The CSS import is required — without it the widget renders unstyled.

## Step 3 — Configure (most-used props)

These are the props you'll reach for most often. Full reference at [`AvatarWidget`](/docs/develop/npm/react/avatar-widget).

**Mode + position:**

```tsx title="floating-bubble.tsx"
<!-- omitted: AvatarWidget -->
```

**Embedded inline:**

```tsx title="inline.tsx"
<div style={{ width: "100%", maxWidth: 600, height: 720 }}>
  <!-- omitted: AvatarWidget -->
</div>
```

**Branding:**

```tsx title="branded.tsx"
<!-- omitted: AvatarWidget -->
```

**Custom greeting:**

```tsx title="greeting.tsx"
<!-- omitted: AvatarWidget -->
```

## Step 4 — Wire your router (Next.js / React Router)

For SPAs, pass the current pathname so the widget can show/hide on specific routes and navigate via your router instead of full reloads:

**Next.js App Router:**

```tsx title="app/layout.tsx"
"use client";
import { usePathname, useRouter } from "next/navigation";
import { AvatarWidget } from "@livelayer/react";
import "@livelayer/react/styles.css";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();
  const router = useRouter();

  return (
    <html>
      <body>
        {children}
        <AvatarWidget
          agentId="agt_abc123"
          pathname={pathname}
          onNavigate={(href) => router.push(href)}
          hideOn={["/admin/*", "/checkout"]}
        />
      </body>
    </html>
  );
}
```

**React Router v6+:**

```tsx title="app.tsx"
import { useLocation, useNavigate } from "react-router-dom";
import { AvatarWidget } from "@livelayer/react";
import "@livelayer/react/styles.css";

export default function App() {
  const { pathname } = useLocation();
  const navigate = useNavigate();

  return (
    <>
      {/* your routes */}
      <AvatarWidget
        agentId="agt_abc123"
        pathname={pathname}
        onNavigate={(href) => navigate(href)}
        hideOn={["/admin/*"]}
      />
    </>
  );
}
```

**Vite / plain React:**

```tsx title="app.tsx"
import { useEffect, useState } from "react";
import { AvatarWidget } from "@livelayer/react";
import "@livelayer/react/styles.css";

export default function App() {
  const [pathname, setPathname] = useState(() => window.location.pathname);

  useEffect(() => {
    const onPop = () => setPathname(window.location.pathname);
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  return <!-- omitted: AvatarWidget -->;
}
```

## Step 5 — React to events

Wire callbacks to track conversations or sync your own UI:

```tsx title="callbacks.tsx"
<AvatarWidget
  agentId="agt_abc123"
  onConnect={() => console.log("session connected")}
  onTranscript={(entries) => {
    const last = entries.at(-1);
    if (last?.final) console.log(`[${last.role}]`, last.text);
  }}
  onAgentState={(state) => {
    // state: "idle" | "listening" | "thinking" | "speaking"
  }}
/>
```

## Where to go next

Now that you have a working widget:

- Make the agent **see** your page — [Page awareness](/docs/develop/npm/react/page-awareness)
- Restrict what it can **do** — [Capabilities](/docs/develop/npm/react/avatar-widget#capabilities)
- Customize **how it looks** — [Theming](/docs/develop/npm/react/theming)
- Build your own **UI from hooks** — [Hooks](/docs/develop/npm/react/hooks)
- Read the **complete prop reference** — [`AvatarWidget`](/docs/develop/npm/react/avatar-widget)
