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

# Getting started: Chat with React

This guide will get you started with Ably Chat on a new React application built with Vite.

You'll learn how to create chat rooms, send and edit messages, and implement realtime features like typing indicators and presence. You'll also cover message history, reactions, and proper connection management.

<img src="https://mintlify.s3.us-west-1.amazonaws.com/ably-docs/images/content/screenshots/getting-started/chat-react-getting-started-guide.png" alt="Screenshot of the completed React Chat application showing a web interface with connection status, a message input field, realtime message display, and a presence indicator showing online users." />

## Prerequisites

### Ably

1. Sign up for an Ably account.

2. Create a [new app](https://ably.com/accounts/any/apps/new), and get your first API key. You can use the root API key that is provided by default, within the **API Keys** tab to get started.

### Create a New Project

1. Create a new React + TypeScript project using Vite. For detailed instructions, refer to the [Vite documentation](https://vitejs.dev/guide/#scaffolding-your-first-vite-project).

<Code>
  ```shell theme={null}
  npm create vite@latest my-chat-react-app -- --template react-ts
  ```
</Code>

2. Setup Tailwind CSS for styling the application. Ensure you import tailwind in your local `App.CSS` file and add it to your `vite.config.ts` file. For installation instructions, see the [Tailwind CSS documentation for Vite](https://tailwindcss.com/docs/guides/vite).

<Code>
  ```shell theme={null}
  npm install tailwindcss @tailwindcss/vite
  ```
</Code>

3. Install the Ably Chat SDK, this will also install the Ably Pub/Sub SDK as a dependency:

<Code>
  ```shell theme={null}
  npm install @ably/chat ably
  ```
</Code>

4. Create a `.env` file in your project root and add your API key:

<Code>
  ```shell theme={null}
  echo "VITE_ABLY_API_KEY={{API_KEY}}" > .env
  ```
</Code>

## Step 1: Set Up the Ably and Chat Client Providers

The Ably Pub/Sub SDK and the Ably Chat SDK expose React hooks and context providers to make it easier to use them in your React components. The [`AblyProvider`](/docs/getting-started/react-hooks#ably-provider) and [`ChatClientProvider`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.ChatClientProvider.html) should be used at the top level of your application, typically in `main.tsx`.

In production, you should use [token authentication](/docs/auth/token) to avoid exposing your API keys publicly, the [`clientId`](/docs/auth/identified-clients) is used to identify the client.

Replace the contents of your `src/main.tsx` file with the following code to set up the providers:

<Code>
  ```react theme={null}
  // main.tsx
  import React from 'react';
  import ReactDOM from 'react-dom/client';
  import * as Ably from 'ably';
  import { ChatClient, LogLevel } from '@ably/chat';
  import { ChatClientProvider } from '@ably/chat/react';
  import { AblyProvider } from 'ably/react';
  import App from './App';

  // Create your Ably Realtime client and ChatClient instances:
  const realtimeClient = new Ably.Realtime({
    key: import.meta.env.VITE_ABLY_API_KEY,
    clientId: 'my-first-client',
  });

  const chatClient = new ChatClient(realtimeClient, {
    logLevel: LogLevel.Info,
  });

  ReactDOM.createRoot(document.getElementById('root')!).render(
    <React.StrictMode>
      <AblyProvider client={realtimeClient}>
        <ChatClientProvider client={chatClient}>
          <App />
        </ChatClientProvider>
      </AblyProvider>
    </React.StrictMode>,
  );
  ```
</Code>

## Step 2: Connect to Ably

Clients establish a connection with Ably when they instantiate an SDK. This enables them to send and receive messages in realtime across channels. This hook must be nested within a `ChatClientProvider`.

In your project, open `src/App.tsx`, and add the following functions:

<Code>
  ```react theme={null}
  // App.tsx
  import { useChatConnection } from '@ably/chat/react';

  function ConnectionStatus() {
    const { currentStatus } = useChatConnection();
    return (
      <div className="p-4 text-center h-full border-gray-300 bg-gray-100">
        <h2 className="text-lg font-semibold text-blue-500">Ably Chat Connection</h2>
        <p className="mt-2">Connection: {currentStatus}!</p>
      </div>
    );
  }

  function App() {
    return (
      <div className="flex flex-col w-[900px] h-full border-1 border-blue-500 rounded-lg overflow-hidden mx-auto font-sans">
        <ConnectionStatus/>
      </div>
    );
  }

  export default App;
  ```
</Code>

Run your application by starting the development server:

<Code>
  ```shell theme={null}
  npm run dev
  ```
</Code>

Open your browser to [localhost:5173](http://localhost:5173), and you will see the connection status reflected in the UI: `"Currently connected!"`.

## Step 3: Create a Room

Now that you have a connection to Ably, you can create a room. Use rooms to separate and organize clients and messages into different topics, or 'chat rooms'. Rooms are the entry object into Chat, providing access to all of its features, such as messages, presence and reactions.

The [`ChatRoomProvider`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.ChatRoomProvider.html) provides access to a specific chat room to all child components in the component tree.

Update your main app component to include the `ChatRoomProvider`:

<Code>
  ```react theme={null}
  import { ChatRoomProvider } from '@ably/chat/react';

  function App() {
    return (
      <ChatRoomProvider name="my-first-room">
        <div className="flex flex-col w-[900px] h-full border-1 border-blue-500 rounded-lg overflow-hidden mx-auto font-sans">
          <ConnectionStatus/>
        </div>
      </ChatRoomProvider>
    );
  }
  ```
</Code>

## Step 4: Send a Message

Messages are how your clients interact with one another and Ably Chat exposes a [`useMessages()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.useMessages.html) hook to interact with the [messages](/docs/chat/rooms/messages?lang=react) feature of the Chat SDK.

Add a new component called `ChatBox` to send and receive messages:

<Code>
  ```react theme={null}
  import { useState } from 'react';
  import { useMessages } from '@ably/chat/react';
  import { ChatMessageEvent, Message, ChatMessageEventType } from '@ably/chat';

  function ChatBox() {
    const [inputValue, setInputValue] = useState('');
    const [messages, setMessages] = useState<Message[]>([]);

    const { sendMessage } = useMessages({
      listener: (event: ChatMessageEvent) => {
        const message = event.message;
        switch (event.type) {
          case ChatMessageEventType.Created: {
            setMessages((prevMessages) => [...prevMessages, message]);
            break;
          }
          default: {
            console.error('Unhandled event', event);
          }
        }
      }
    });

    const handleSend = () => {
      if (!inputValue.trim()) return;
      sendMessage({ text: inputValue.trim() }).catch((err) =>
        console.error('Error sending message', err))
      setInputValue('');
    };

    return (
    <div className="flex flex-col w-full h-[600px]">
      <div className="flex-1 p-4 overflow-y-auto space-y-2">
        {messages.map((msg: Message) => {
          const isMine = msg.clientId === 'my-first-client';
          return (
            <div key={msg.serial} className={`max-w-[60%] rounded-2xl px-3 py-2 shadow-sm ${
              isMine ? 'bg-green-200 text-gray-800 rounded-br-none' : 'bg-blue-50 text-gray-800 rounded-bl-none'
            }`}>
              {msg.text}
            </div>
          );
        })}
      </div>
      <div className="flex items-center px-2 mt-auto mb-2">
        <input
          type="text"
          placeholder="Type your message..."
          className="flex-1 p-2 border border-gray-400 rounded outline-none bg-white"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          onKeyDown={(event) => {
            if (event.key === 'Enter') {
              handleSend();
            }
          }}
        />
        <button
          className="bg-blue-500 text-white px-4 ml-2 h-10 flex items-center justify-center rounded hover:bg-blue-600 transition-colors"
          onClick={handleSend}
        >
          Send
        </button>
      </div>
    </div>
    );
  }
  ```
</Code>

Add the `ChatBox` component to your main app component:

<Code>
  ```react theme={null}
  function App() {
    return (
      <ChatRoomProvider name="my-first-room">
        <div className="flex flex-col w-[900px] h-full border-1 border-blue-500 rounded-lg overflow-hidden mx-auto font-sans">
          <ConnectionStatus/>
          <ChatBox/>
        </div>
      </ChatRoomProvider>
    );
  }
  ```
</Code>

## Next Steps

Continue to explore the documentation with React as the selected language:

* Understand [token authentication](/docs/auth/token) before going to production
* Read more about using [rooms](/docs/chat/rooms?lang=react) and sending [messages](/docs/chat/rooms/messages?lang=react)
* Find out more regarding [presence](/docs/chat/rooms/presence?lang=react)
* Read into pulling messages from [history](/docs/chat/rooms/history?lang=react) and providing context to new joiners

Explore the [Ably CLI](https://www.npmjs.com/package/@ably/cli) further, or check out the [Chat JS API references](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/modules/chat-js.html) for additional functionality.
