LevelChatLevelChatDocs
PreJoin

Components

PreJoin

Green-room gate — preview, devices, name, Join CTA.

PreJoin is the pre-call green-room gate. It owns the getUserMedia preview, the device enumeration loop, the live mic VU meter, and the name input — your app just receives the chosen options and runs its room-join sequence.

Install

pnpm add @levelchat/react-components @levelchat/web

Requirements

  • Reactreact and react-dom ^18 || ^19 (peer dependency).
  • LevelChat Web SDK@levelchat/web ^0.2.4 (peer dependency, wires hook-driven mode to the live Room).
  • Provider — wrap the tree in <LevelChatProvider> from @levelchat/web-react so hook-driven mode can subscribe to room events. Prop-driven demos work without it.
  • Styles — import the brand tokens + kit stylesheet exactly once at the app entry, before any kit component renders.

In Next.js (App Router), import the stylesheets at the top of your root layout:

TypeScript (TSX)
// app/layout.tsx
import '@levelchat/brand/tokens.css';
import '@levelchat/react-components/styles.css';

In Vite (or any plain React app), import them at the top of your entry module:

TypeScript (TSX)
// src/main.tsx
import '@levelchat/brand/tokens.css';
import '@levelchat/react-components/styles.css';

Basic usage

Headless hook

Use usePreJoin when you want a wholly bespoke green-room layout. The hook manages the preview lifecycle and returns ready-to-bind state:

import { usePreJoin } from '@levelchat/react-components';

function CustomGreenRoom() {
  const { preview, devices, name, setName, micOn, setMicOn, ready, join } = usePreJoin();
  return (
    <>
      <video ref={preview.videoRef} playsInline muted />
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <button disabled={!ready} onClick={() => onJoinRoom(join())}>Join</button>
    </>
  );
}

Slot composition

<PreJoin onJoin={join}>
  <PreJoin.Preview />
  <PreJoin.NameInput label="Display name" />
  <PreJoin.DeviceMenu kind="mic" />
  <PreJoin.DeviceMenu kind="camera" />
  <PreJoin.DeviceMenu kind="speaker" />
  <PreJoin.MicLevel />
  <PreJoin.JoinButton>Join meeting</PreJoin.JoinButton>
</PreJoin>

Theming

  • --lc-brand-primary — Join button background + VU meter bars.
  • --lc-surface-base, --lc-border-default — form card.
  • --lc-text-primary, --lc-text-secondary — copy.

Props

PropTypeDefaultNotes
onJoin(opts: PreJoinJoinOptions) => void | Promise<void>Called when the user submits. Required.
initialDisplayNamestring''Pre-fill the name field.
titlestringReady to join?Headline above the form.
subtitlestringOptional subtitle / topic.
statePreJoinStateInject your own hook output (tests, Storybook).
PreJoin — LevelChat Docs