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:
  1. Pop out this window in a new tab.
  2. Enter a message and choose a color for the message.
  3. Click on the "Publish" button to broadcast the message.
  4. The message will be displayed in all open windows or tabs, based on the color selected.
See @nayaabh/react-broadcast-channel demo in actionSee @nayaabh/react-broadcast-channel demo in action

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}`;
}


/> Devy.in© 2025Made from scratch with ❤️ & 🍵