> ## 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.

# Typing Indicators

Typing indicators enable you to display which users are currently writing a message in a room. This feature can be used to display a message such as *Sandi is typing...*, or when a certain threshold is reached you could instead display *Multiple people are typing...*

## Subscribe to Typing Events

<Tabs>
  <Tab name="JavaScript">
    <Code>
      ```javascript theme={null}
      const {unsubscribe} = room.typing.subscribe((event) => {
        console.log("Currently typing: ", event.currentlyTyping);
      });
      ```
    </Code>
  </Tab>

  <Tab name="React">
    <Code>
      ```react theme={null}
      import { useTyping } from '@ably/chat/react';

      const MyComponent = () => {
        const { currentlyTyping, roomError } = useTyping({
          listener: (typingEvent) => {
            console.log('Typing event received: ', typingEvent);
          },
        });

        return (
          <div>
            {roomError && <p>Typing Error: {roomError.message}</p>}
            <p>Currently typing: {Array.from(currentlyTyping).join(', ')}</p>
          </div>
        );
      };
      ```
    </Code>
  </Tab>

  <Tab name="Swift">
    <Code>
      ```swift theme={null}
      let typingSubscription = room.typing.subscribe()
      for await typing in typingSubscription {
        typingInfo = typing.currentlyTyping.isEmpty ? "" :
                      "Typing: \(typing.currentlyTyping.joined(separator: ", "))..."
      }
      ```
    </Code>
  </Tab>

  <Tab name="Android / Kotlin">
    <Code>
      ```android theme={null}
      import com.ably.chat.Room
      import com.ably.chat.extensions.compose.collectAsCurrentlyTyping

      @Composable
      fun TypingComponent(room: Room) {
        val currentlyTyping by room.collectAsCurrentlyTyping()

        Text("Currently typing: ${currentlyTyping.joinToString(", ")}")
      }
      ```
    </Code>
  </Tab>
</Tabs>

## Set Typing Status

<Tabs>
  <Tab name="JavaScript">
    <Code>
      ```javascript theme={null}
      await room.typing.keystroke();
      await room.typing.stop();
      ```
    </Code>
  </Tab>

  <Tab name="React">
    <Code>
      ```react theme={null}
      import { useTyping } from '@ably/chat/react';

      const MyComponent = () => {
        const { keystroke, stop, currentlyTyping, roomError } = useTyping();
        
        const handleKeystrokeClick = () => {
          keystroke();
        };

        return (
          <div>
            {roomError && <p>Typing Error: {roomError.message}</p>}
            <button onClick={handleKeystrokeClick}>Start Typing</button>
            <p>Currently typing: {Array.from(currentlyTyping).join(', ')}</p>
          </div>
        );
      };
      ```
    </Code>
  </Tab>

  <Tab name="Swift">
    <Code>
      ```swift theme={null}
      try await room.typing.keystroke()
      try await room.typing.stop()
      ```
    </Code>
  </Tab>

  <Tab name="Android / Kotlin">
    <Code>
      ```android theme={null}
      import com.ably.chat.Room

      @Composable
      fun TypingKeystrokeComponent(room: Room) {
        val coroutineScope = rememberCoroutineScope()
        var text by remember { mutableStateOf("") }

        TextField(
          value = text,
          onValueChange = { newText ->
            text = newText
            coroutineScope.launch {
              room.typing.keystroke()
            }
          },
          label = { Text("Type a message") }
        )
      }
      ```
    </Code>
  </Tab>
</Tabs>

## Next Steps

* Learn about [room reactions](/docs/chat/rooms/reactions)
* Explore [room occupancy](/docs/chat/rooms/occupancy)
* Understand [messages](/docs/chat/rooms/messages)
