Appearance
Shared Slot State
Use the slot-state helpers to share state between the EXTENSION_SLOT_BACKGROUND slot and visual slots. The background slot owns the state. Visual slots read it and send partial updates through the same channel.
The state is available only to slots of the current extension client. It is not persistent storage or a broadcast to other viewers.
Roles
| Slot | Helper | Responsibility |
|---|---|---|
| Background slot | createSlotStateHost | Owns and updates the shared state. |
| Visual slot | createSlotStateClient | Reads and updates the shared state. |
Create one host for each channel in the background slot. Create a client in each visual slot that needs the state. Every participant must use the same channel string.
Example: Shared Counter
This example uses one background slot and one React visual slot. Additional visual slots can create clients with the same channel: 'score'.
1. Create the host in the background slot
The background slot is non-visual and remains available to coordinate the extension. It owns the shared score and does not render UI.
ts
import { createExtHelper } from '@stripchatdev/ext-helper';
import { createSlotStateHost } from '@stripchatdev/ext-helper/helpers';
type ScoreState = {
score: number;
};
const extHelper = createExtHelper();
export const init = () => {
const scoreState = createSlotStateHost<ScoreState>({
channel: 'score',
extHelper,
initialState: { score: 0 },
});
return () => scoreState.unsubscribe();
};Create the host once in the background slot. The background slot can also call scoreState.setState() when its own event handlers change the state.
2. Create a client in a visual slot
The visual slot reads the latest background snapshot and sends partial updates back to the host. It does not own the score.
Example in React:
tsx
import { createExtHelper } from '@stripchatdev/ext-helper';
import { useSlotState } from '@stripchatdev/ext-helper/helpers/react';
type ScoreState = {
score: number;
};
const extHelper = createExtHelper();
export function ScorePanel() {
const { isLoading, state, setState } = useSlotState<ScoreState>({
channel: 'score',
extHelper,
});
if (isLoading || !state) {
return <p>Loading score...</p>;
}
return (
<button onClick={() => void setState({ score: state.score + 1 })}>
Score: {state.score}
</button>
);
}The client starts with isLoading: true and state: null. After the initial state is available, setState() sends a shallow partial update to the host and the client updates when the host publishes the new state. Nested objects must be updated explicitly.
Framework-Neutral Visual Slot
Use createSlotStateClient in a non-React visual slot. Subscribe to changes and read the current state with getSnapshot().
ts
import { createExtHelper } from '@stripchatdev/ext-helper';
import { createSlotStateClient } from '@stripchatdev/ext-helper/helpers';
const extHelper = createExtHelper();
const state = createSlotStateClient<{ score: number }>({
channel: 'score',
extHelper,
});
const unsubscribe = state.subscribe(() => {
const snapshot = state.getSnapshot();
if (!snapshot.isLoading && snapshot.state) {
renderScore(snapshot.state.score);
}
});
void state.setState({ score: 10 });
// Call this when the visual slot is disposed.
unsubscribe();Rules
- Create one host per shared channel in the background slot.
- Create clients only in visual slots that need the state.
- Use exactly the same channel string for the host and its clients.
- Keep the background slot as the source of truth.
- Use
setState()for shallow partial updates. - Handle the initial
isLoadingandstate: nullvalues. - Unsubscribe clients when their visual slot is disposed.
- Unsubscribe the host when the background slot is torn down.
Related Documentation
- Extension Slots explains the background and visual slot roles.
- Slots Communication documents the underlying local whisper mechanism.
- SDK helpers lists the helper entrypoints.