> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vocode.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# React Quickstart

> Get up and running using React

# Installation

`npm install vocode`

Or, start from our [Replit template](https://replit.com/@vocode/Simple-Conversation).

# Usage

## Setting up the conversation

Our self-hosted backend allows you to expose a websocket route that operates like `StreamingConversation`.

To get started, clone the Vocode repo or copy the [client backend app](https://github.com/vocodedev/vocode-python/tree/main/apps/client_backend) directory.

### Environment

Copy the `.env.template` and add your API keys.

```
cp .env.template .env
```

You'll need:

* [Deepgram](https://deepgram.com) (for speech transcription)
* [OpenAI](https://platform.openai.com) (for the underlying agent)
* [Azure](https://azure.microsoft.com/en-us/products/cognitive-services/text-to-speech/) (for speech synthesis)

```
DEEPGRAM_API_KEY=
OPENAI_API_KEY=
AZURE_SPEECH_KEY=
AZURE_SPEECH_REGION=
```

### Running with Docker

From the `client_backend` directory:

```
docker build -t vocode-client-backend .
docker run --env-file=.env -p 3000:3000 -t vocode-client-backend
```

### Running with Python

```
pip3 install vocode
uvicorn main:app --port 3000
```

You now have a server with a Vocode websocket route at localhost:3000! You can now use the `useConversation` hook with your self-hosted backend as follows:

```typescript theme={null}
import { useConversation } from "vocode";

const { status, start, stop, error, analyserNode } = useConversation({
  backendUrl: "<YOUR_BACKEND_URL>", // looks like ws://localhost:3000/conversation or wss://asdf1234.ngrok.app/conversation if using ngrok
  audioDeviceConfig: {},
});
```

Use the `status`, `start`, and `stop` objects within your React components to control conversations with your self-hosted backend, e.g.

```jsx theme={null}
<>
  {status === "idle" && <p>Press me to talk!</p>}
  {status == "error" && error && <p>{error.message}</p>}

  <button
    disabled={["connecting"].includes(status)}
    onClick={status === "connected" ? stop : start}
  ></button>
</>
```
