Headless / Realtime
Join a room and see who is here
Build room presence with the room's shared state and capability-aware controls.
37 public parts · 3examples
@slices.sh/realtime/headlessView as Markdown ↗Your design. Our behavior.
Explore the tree to see what each part controls. Gates reveal the relevant state; roots outline their scope.
Join.Root · Scope
Installation
Choose what your component needs. Run these commands in an initialized Next.js app.
Before you start
The steps below run in a Next.js app with shadcn set up (it has a components.json). In an existing Next.js app, such as one from create-next-app, set shadcn up first:
npx shadcn@latest init -t next -b base -p novaOr start fresh: the slices CLI creates the app and sets it up.
npx slices.sh installInstall the service registry
Adds services/index.ts, which import "@/services" loads. A provider setup writes the same file, so skip this if your app has one.
npx add servicesInstall the headless library
npmAdd the React parts to your app, then compose them with your own elements.
npm install @slices.sh/realtime@^0.1.6Import from @slices.sh/realtime/headless.
Install the service
Connect the parts to a provider. Skip this step if this service is already configured in your app.
npx add realtime.p2p-meshAdds service configuration and API routes to your app, with the provider dependencies. For a headless composition, add import "@/services" after "use client".
The slices CLI installs the service and provisions its required resources in one command.
Provider setup notes
Only for “A room conversation”: npm install @slices.sh/composer@^0.1.4
Start small
Parts bring the behavior. Use their default elements, or supply your own with render.
"use client"// services/index.ts comes from https://slices.sh/r/services.json (or any provider setup)import "@/services"import { Room } from "@slices.sh/realtime/headless"export function Example() { return ( <Room.Root room="lobby"> <Room.Peers> <Room.Peer> <Room.PeerAvatar /> <Room.PeerName /> </Room.Peer> </Room.Peers> <Room.Reconnecting>Reconnecting…</Room.Reconnecting> </Room.Root> )}People in the same room see each other. The provider handles presence and reconnection.
API reference
Every public part used by this experience is listed below. Gates render children without adding an element. Element parts accept native element props and render; function children receive the state declared in their props. Scopes provide context rather than a visual element.
Join.Rootscope
Root holds the preview tracks and the chosen name, and hands them to the room. Toggle kind="camera" | "microphone" switches the preview. Level writes the preview microphone's level as --level for a meter; @slices.sh/voice-canvas can draw the same signal as bars. Name is the name field, prefilled from auth when it is configured. Inside counts who is in the room and Faces shows them. Submit joins.
Props
5 documented props
| Prop | Type | Default |
|---|---|---|
configThe realtime config, a slug from the registry ( | string | — |
enabledLeft out or | Enabled | — |
roomRequired | string | — |
onJoinedOnce somebody has gone in: where a page sends them to the room, when it is elsewhere. | () => void | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-root.tsx
Join.Waitinggate
Still at the door.
Required scope
Join.Waiting must be inside <Join.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-waiting.tsx
Join.Nameinput · <input>
The name you go in under. Left empty, you go in as the animal its placeholder shows.
Required scope
Join.Name must be inside <Join.Root>.
Props
2 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-name.tsx
Join.Toggleaction · <button>
The camera or the microphone, at the door. `data-active` while it is on. Its own part rather than `Room.MediaToggle`, which is disabled until there is a room to send into: here there never is one, and the whole point is to try the camera before there is.
Required scope
Join.Toggle must be inside <Join.Root>.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
kindRequired | "audio" | "video" | — |
childrenContent rendered inside this part. | ReactNode | ((state: { on: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-toggle.tsx
Join.Levelcontent · <span>
Your microphone at the door, as `--level` from 0 to 1: say something and watch it move.
Required scope
Join.Level must be inside <Join.Root>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-level.tsx
Join.Insidegate
Who is already in, in words: "Amara and Ben are in this call". Nothing where the room could not be seen into, because saying "nobody is here" about a room nobody could look at would be a guess dressed as a fact. → docs/rules/capability-honesty.md
Required scope
Join.Inside must be inside <Join.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: Inside) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-inside.tsx
Join.Facesscope
The faces of whoever is inside, each in a peer's scope, so `Room.PeerAvatar` and `Room.PeerName` draw them as they would in the room.
Required scope
Join.Faces must be inside <Join.Root>.
Props
3 documented props
| Prop | Type | Default |
|---|---|---|
maxThe most faces to show; the words beside them say how many more. | number | 4 |
group | ComponentType<{ children?: ReactNode }> | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-faces.tsx
Join.Submitaction · <button>
Goes in, with the camera, microphone and name chosen here. `data-pending` once pressed, while the page the room is on loads.
Required scope
Join.Submit must be inside <Join.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { joined: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-submit.tsx
Join.Joinedgate
Through the door: where the room itself goes, when it is on the same page.
Required scope
Join.Joined must be inside <Join.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/join-joined.tsx
Room.Rootscope
The room everything under here is in. Joining happens in the provider's effect rather than here, so a component that renders twice before it commits does not put two peers in the roster for one tab. A root inside a root for the same room shares its connection, and its follow too: a presence list placed on a canvas has to move the canvas when somebody on it is picked, and two follows would be two lists of whom somebody is following. A root inside a root for the same room needs no service of its own, and says nothing when there is none. Optional with no service, or off, there is no room: its status is "off", so every gate stays shut and `Room.Present` hides what the room is drawn inside, and its sink is switched off, so a Composer inside renders nothing. → ../hooks/use-realtime-scope.ts
Props
8 documented props
| Prop | Type | Default |
|---|---|---|
configThe realtime config, a slug from the registry ( | string | — |
enabledLeft out or | Enabled | — |
roomRequired | string | — |
profileWho this browser shows itself as. Without one, a visitor gets an animal of their own; and somebody signed in is their session's name and picture whatever this says. | PeerProfile | — |
perPersonOne person across this browser's tabs: every tab takes the same name, the one a screen that counts people shows once. Off, each tab is somebody of its own. | boolean | — |
mediaOff, the transport never asks for a camera or a microphone. | boolean | — |
captionsCaptions start shown; each person can still hide them for themselves. | boolean | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/room-root.tsx
Room.Joininggate
Still finding the room.
Required scope
Room.Joining must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/room-states.tsx
Room.Failedgate
The room could not be joined, for a reason nothing here can mend. `denied` is told apart from the rest because the remedies are opposite: one is a permission, the other is a retry. A full room is not here at all — it is `Room.Full`, because it is the one refusal that mends itself when somebody leaves. A server that lacks configuration is not here either: it is `Room.MissingConfiguration`, which says so in words for somebody to report, instead of this one's "could not be reached" beside it.
Required scope
Room.Failed must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { denied: boolean }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/room-failed.tsx
Room.MissingConfigurationgate
The server that holds the rooms lacks a variable it needs, such as its room table. `Configuration.Missing` for this family, narrowed to the room service: a call that also transcribes could have a transcription key missing, and that is the captions' notice, not a room's. It stands where `Room.Failed` would, and works outside a root as well, because a door has learned it from its first look at the room before anybody has joined anything.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { scopes: readonly string[] }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/room-missing-configuration.tsx
Room.Fullgate
The room is full. Its own gate rather than a kind of failure, because it is the one refusal that is nobody's fault and fixes itself: a mesh holds as many people as `services/realtime/config.ts` says it holds, and the next person to leave makes room. The transport keeps retrying, so what belongs here is a sentence and a way to try now — never an apology for a broken app.
Required scope
Room.Full must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/room-full.tsx
Room.Leftgate
This browser closed the room on purpose. The service calls it `idle`, which is also what it calls a room nothing has been tried on yet, and the two owe a person opposite screens: one is a spinner, and this one is a door back in. Without it a meeting somebody left became an empty grid with a live control bar.
Required scope
Room.Left must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/room-left.tsx
Room.Rejoinaction · <button>
Take the room again. Nothing at all when the room cannot be reopened — one handed in from outside is somebody else's to reopen — because a button that cannot work is worse than no button. → docs/rules/capability-honesty.md It takes the focus when it appears into a page whose focus has fallen to nothing, which is what pressing Leave does: the button that had the focus is gone with the rest of the room, and somebody on a keyboard was left starting again from the top of the page. (WCAG 2.4.3)
Required scope
Room.Rejoin must be inside <Room.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/rejoin.tsx
Room.Presentgate
In the room, or on the way in: everything but having left it or been refused it. What a room is drawn inside — its tiles, its controls, what it says about a camera — so that leaving takes all of it away and `Room.Left` has the screen to itself. Without it the grid and the control bar stayed up behind "You left the meeting", still showing everybody who was in it. Being refused (unreachable, denied, full: a full room is a failed status) takes the room away the same way, and so does no service to join (an optional root without one), so `Room.Failed` and `Room.Full` are not drawn under a "Live" header and controls that reach nobody.
Required scope
Room.Present must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/room-present.tsx
Room.Reconnectinggate
The link dropped and is being rebuilt. Its own state rather than a kind of failure, because nothing is lost and nobody has to do anything: a banner offering "Try again" here would be offering what is already happening.
Required scope
Room.Reconnecting must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/reconnecting.tsx
Room.Connectedgate
In the room, with a live signalling path.
Required scope
Room.Connected must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/connected.tsx
Room.Rosterscope
A list of people somebody can search, for a room too big to scan.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/roster.tsx
Room.RosterSearchinput · <input>
Narrows the roster around it to the names that contain what is typed.
Required scope
Room.RosterSearch must be inside <Room.Roster>.
Props
2 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/roster-search.tsx
Room.NoMatchesgate
Somebody searched the roster and nobody's name has that in it.
Required scope
Room.NoMatches must be inside <Room.Roster>.
Room.NoMatches must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { query: string }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/no-matches.tsx
Room.Peersscope
Who is here, each in their own scope: you first, then everybody in the order they came. Peers are connections, so two tabs are two of them. Collapsing per person is a display decision and lives here rather than in the wire format, which is why it is a prop. Inside a `Room.Roster`, only the names matching its search are listed.
Required scope
Room.Peers must be inside <Room.Root>.
Props
7 documented props
| Prop | Type | Default |
|---|---|---|
perPersonOne row per person rather than per connection: two tabs become one entry. | boolean | false |
includeMeWhether you are in the list. A face pile usually wants you out of it. | boolean | true |
maxThe most items a pile may take, counting its "+N". Past it the pile shows one face fewer
and | number | — |
overflowOfOnly those a pile of this size leaves out: what its "+N" opens. | number | — |
limit@deprecated A hard cut with no room kept for the count; use | number | — |
groupWhat the items are grouped in. A Motion presence group here is what lets a face leave rather than vanish, without this part knowing anything about animation. | ComponentType<{ children?: ReactNode }> | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/peers.tsx
Room.Peercontent · <li>
One peer's row or tile. `data-active` while the connection is actually live.
Required scope
Room.Peer must be inside <Room.Peers>.
Props
2 documented props · Native <li> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { connected: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/peer.tsx
Room.PeerAvatarcontent · <span>
A peer's face: their picture once it has loaded, their initials until then and for good if it never does, with their colour as `--peer` and the ink that reads on it as `--peer-ink`, for the skin to paint with. → ./peer-look.ts The picture is painted as the face's background and the initials are dropped when it arrives, so a skin's size, shape and colour work unchanged and a slow or dead address costs nothing but the picture. → ./use-peer-picture.ts Named after the person rather than after the two letters standing in for them: a pile of these is the whole of a presence list, and without a name it reads out as "AB CD EF". The name is the peer's own and is never a word a skin or a copy chooses, so it is locked here rather than asked for. (WCAG 1.1.1)
Required scope
Room.PeerAvatar must be inside <Room.Peers>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/peer-avatar.tsx
Room.PeerNamecontent · <span>
Peers repeats the people here, up to max, and Peer is one scope. PeerName, PeerAvatar (with --peer colour), PeerStatus (the data path, in words), PeerActivity (here, idle, away) describe the peer in scope. PeerCount counts them. IsMe, NotMe and Me pick out you. MorePeers gives { hidden, names } for the ones a pile leaves out. Unreachable renders for a peer this browser has no route to, which needs a relay. Roster, RosterSearch and NoMatches make a searchable list for a big room.
Required scope
Room.PeerName must be inside <Room.Peers>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/peer-name.tsx
Room.PeerStatuscontent · <span>
Whether this peer's data path is open, in words. The dot beside an avatar carries the most interesting fact on the screen — recorded in the roster, or actually reachable — and carries it in a colour, which is no use to anybody who cannot see it. Usually rendered visually hidden beside the dot. (WCAG 1.4.1) `reachable` is `null` while the link is still being made, which is a third thing and not a shade of the other two: for a second or two after somebody joins, nobody knows yet. → docs/rules/capability-honesty.md
Required scope
Room.PeerStatus must be inside <Room.Peers>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { reachable: boolean | null }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/peer-status.tsx
Room.PeerActivitycontent · <span>
Where a peer's attention is — here, idle, away — and what they say they are doing. One part for the dot and the words both, because the dot is the words in a colour: a skin draws the dot from `data-state` and a copy says it from the state, so the two can never disagree. `data-state` is absent while the peer has said nothing, which draws no dot rather than a green one nobody earned. → docs/rules/capability-honesty.md
Required scope
Room.PeerActivity must be inside <Room.Peers>.
Room.PeerActivity must be inside <Room.Root>.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: ActivityState) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/peer-activity.tsx
Room.NotMegate
The person in scope is somebody else — where a control about them makes no sense for you.
Required scope
Room.NotMe must be inside <Room.Peers> or <Room.Seats>.
Room.NotMe must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/not-me.tsx
Room.Unreachablegate
The room names this peer and this browser has no route to them. Told apart from a camera that is off, which looks identical and means the opposite: one is a choice somebody made and the other is a network that needs a relay. A mesh over STUN alone cannot reach a peer behind a symmetric NAT at all, and the only honest thing a tile can do is say so. → resources/turn/README.md Also told apart from a link that is still being made, which looks identical again and is what every peer's first second in the room looks like: a badge that appeared the instant somebody joined and went away when their channel opened would accuse the network of something ordinary, and be ignored by the time it was true. → hooks/realtime/use-link-settled.ts
Required scope
Room.Unreachable must be inside <Room.Peers>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/unreachable.tsx
Room.IsMegate
The peer in scope is you — or your other tab, which is you too.
Required scope
Room.IsMe must be inside <Room.Peers>.
Room.IsMe must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/is-me.tsx
Room.Megate
You, in the scope of a peer: for the one place on a screen that is yours alone, beside the faces of everybody else rather than first among them. Nothing until you have joined.
Required scope
Room.Me must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/me.tsx
Room.PeerCountcontent · <span>
How many are here and reachable, counting you. → per-person.ts `reachableIn`
Required scope
Room.PeerCount must be inside <Room.Root>.
Props
3 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
perPersonPeople rather than connections, so somebody in two tabs is counted once. | boolean | false |
childrenContent rendered inside this part. | ReactNode | ((state: { count: number }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/peer-count.tsx
Room.MorePeerscontent · <span>
The people a pile leaves out: how many, and who. Who as well as how many, because a "+5" nobody can expand is a number. The names reach the content function, so a screen can say them to a screen reader and open them in a list. Nothing at all when everybody fits.
Required scope
Room.MorePeers must be inside <Room.Root>.
Props
6 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
maxThe same number the pile beside it was given as its | number | — |
limit@deprecated The pile's old hard cut; use | number | — |
perPerson | boolean | false |
includeMe | boolean | true |
childrenContent rendered inside this part. | ReactNode | ((state: MorePeersState) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/more-peers.tsx
Room.Alonegate
You are in the room and nobody else is: the moment a screen can say what it needs a second connection for. Another tab of yours is somebody here, which is how a person alone tries a room out. Somebody the roster names that nothing reaches is not here, as Room.PeerCount does not count them. Not while joining or failed, when nobody being here is not yet, or not ever, the story.
Required scope
Room.Alone must be inside <Room.Root>.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/alone.tsx
Room.Announcercontent · <p>
What just happened in the room, for somebody who cannot see it happen. A polite live region, always in the DOM and usually empty: a region that appears with its first sentence is a region a screen reader was not watching when the sentence arrived. The words are the pattern's, because they are words. → docs/rules/words-in-copy-looks-in-skin.md
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { news: RoomNews | null }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/announcer.tsx
Room.Leaveaction · <button>
Close the room. Nothing to do once it is closed, which is what `Room.Rejoin` is for.
Required scope
Room.Leave must be inside <Room.Root>.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/realtime/src/headless/leave.tsx
When something is missing
- No service configuration
- Install the realtime setup below and import "@/services". Required service roots report missing setup; gates do not replace that configuration.
- Missing capability or parent scope
- Follow each part’s context requirements and the example composition. Capability-aware controls hide when the provider cannot perform their action.