Info:
This is release candidate documentation for Stream Chat React SDK v15. For the latest stable version, see the latest version (v14).

Location hooks

This hook keeps the current user's live locations updated. It's exported from stream-chat-react.

Location sharing, and why live locations need this hook, is explained on Location sharing. The location being shared from the composer is in locationComposer.state: see Composer hooks.

The entry gives the signature, then:

  • Returns: what the hook gives back.
  • Reads: the store or the context it reads.
  • Re-renders: what makes the component render again.
  • Needs: where the component must sit, and what the hook does outside that place.

useLiveLocationSharingManager

Creates the manager that sends the user's position to every live location they're sharing.

useLiveLocationSharingManager(params: {
  client?: StreamChat | null;
  getDeviceId?: () => string;
  watchLocation: WatchLocation;
}): LiveLocationManager | null

The params:

  • client: the client whose user shares the locations.

  • watchLocation: (handler) => unsubscribe. It starts watching the device's position and calls handler with each { latitude, longitude }. The manager calls it while at least one live share is active, and calls the returned function when none is left.

  • getDeviceId: the id of the device the shares come from. By default it's built from the device type, the browser and the user id, such as web-desktop-chrome-ann.

  • Returns: a LiveLocationManager, or null while client is null or undefined. The hook starts it with LiveLocationManager.init() and stops it when the component unmounts or the hook creates another one.

  • Reads: no store and no context. The manager keeps its own state in manager.state.

  • Re-renders: never by itself. A new client, getDeviceId or watchLocation creates a new manager, so declare the functions at module scope or with useCallback.

  • Needs: nothing: it takes the client as a param and works outside Chat. The client must have a connected user, or creating the manager throws. useCreateChatClient returns null until the user is connected, so its result can be passed as it is.

Call it once, in a component that stays mounted while the user is signed in. Two managers would both send each position. This one also shows how many live locations are active:

import type { LiveLocationManagerState, WatchLocation } from "stream-chat";
import {
  useChatContext,
  useLiveLocationSharingManager,
  useStateStore,
} from "stream-chat-react";

const watchLocation: WatchLocation = (handler) => {
  const watchId = navigator.geolocation.watchPosition((position) => {
    handler({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude,
    });
  });
  return () => navigator.geolocation.clearWatch(watchId);
};

const sharesSelector = ({ messages }: LiveLocationManagerState) => ({
  messages,
});

export const LiveLocationStatus = () => {
  const { client } = useChatContext();
  const manager = useLiveLocationSharingManager({ client, watchLocation });
  const { messages } = useStateStore(manager?.state, sharesSelector) ?? {};

  if (!messages?.size) return null;
  return <span>Sharing your live location in {messages.size} messages</span>;
};

Live location state without a hook

stream-chat-react has no hook for the manager's state. Read manager.state with useStateStore, as LiveLocationStatus does:

  • ready: whether the manager has loaded the user's active live locations.
  • messages: a Map from message id to each live location the user is sharing, with its end_at.

A location shown in a message is message.shared_location, and changes with the message's message.updated event.