React Broadcast Channel Demo ✨
This is a demo page for the @nayaabh/react-broadcast-channel
library. Open this page in multiple tabs or windows to see how messages are broadcasted between them.
How It Works
Steps to use the demo:
- Pop out this window in a new tab.
- Enter a message and choose a color for the message.
- Click on the "Publish" button to broadcast the message.
- The message will be displayed in all open windows or tabs, based on the color selected.

Code
Sample code for above example
🔴🟡🟢
demo-code.jsx
"use client";
import { Box, Button, ListItem, ListItemText, Paper, TextField, Typography, useTheme } from "@mui/material";
import { useBroadcastState } from "@nayaabh/react-broadcast-channel";
import { useCallback, useEffect, useState } from "react";
import { FixedSizeList, ListChildComponentProps } from "react-window";
const CHANNEL_NAME = "BroadcastChannel-001";
type MessageType = {
message: string;
color: string;
timeStamp: string;
};
export const BroadcastSandbox = () => {
const [message, setMessage] = useBroadcastState<MessageType>(CHANNEL_NAME);
const [logs, setLogs] = useState<MessageType[]>([]);
const theme = useTheme();
const onPublish = useCallback((e: any) => {
e.preventDefault();
const data = new FormData(e.target);
const text = data.get("message") as string;
const color = data.get("color") as string;
const dateTime = getTimestamp();
setMessage({ message: text, color, timeStamp: dateTime });
}, []);
useEffect(() => {
if (message) {
setLogs((logs) => [message, ...logs]);
}
}, [message]);
return (
<>
<Box
component="form"
onSubmit={onPublish}
sx={{
display: "flex",
flexDirection: "row",
gap: 2,
marginBlock: 2,
}}
>
<TextField
name="message"
variant="outlined"
label="Enter a message"
size="small"
sx={{
flexGrow: 1,
}}
slotProps={{
htmlInput: {
maxLength: 100,
},
}}
/>
<Box
component={"input"}
type="color"
name="color"
defaultValue={theme.palette.grey[500]}
sx={{
alignSelf: "center",
}}
/>
<Button type="submit" variant="contained" color="primary">
Publish
</Button>
</Box>
<Paper
variant="outlined"
sx={{
width: "100%",
padding: 1,
}}
>
<FixedSizeList height={200} width="100%" itemSize={32} itemCount={logs.length} overscanCount={5}>
{(props: ListChildComponentProps) => {
const { index, style } = props;
const { message, timeStamp, color } = logs[index] || {};
const log = `${timeStamp} - ${message}`;
return (
<ListItem style={style} id={index} component="div" disablePadding dense>
<ListItemText
primary={
<Typography variant="caption" sx={{ color }}>
{log}
</Typography>
}
/>
</ListItem>
);
}}
</FixedSizeList>
</Paper>
</>
);
};
function getTimestamp() {
const date = new Date();
const year = date.getFullYear();
const month = `${date.getMonth() + 1}`.padStart(2, "0");
const day = `${date.getDate()}`.padStart(2, "0");
const hour = `${date.getHours()}`.padStart(2, "0");
const minute = `${date.getMinutes()}`.padStart(2, "0");
const second = `${date.getSeconds()}`.padStart(2, "0");
const millisecond = `${date.getMilliseconds()}`.padStart(2, "0");
return `${year}-${month}-${day} ${hour}:${minute}:${second}.${millisecond}`;
}