Blog>
Snippets

Connecting to a Shared Web Worker

Utilize useSyncExternalStore to manage and synchronize state across multiple tabs with a shared Web Worker.
// shared-worker.js - The Shared Web Worker file
const connections = [];
let state = {};

self.onconnect = function(event) {
  const port = event.ports[0];
  connections.push(port);

  port.onmessage = function(event) {
    if (event.data.type === 'SET_STATE') {
      state = { ...state, ...event.data.payload };
      connections.forEach(p => p.postMessage({ type: 'STATE_UPDATED', state }));
    }
  };

  port.start();
};
This is the shared worker (shared-worker.js) that handles connections and manages state. It listens for incoming messages to update the state and broadcasts the updated state to all connected tabs.
// main.js - Your client-side code to connect to the Shared Web Worker
import { useSyncExternalStore } from 'react';

const worker = new SharedWorker('shared-worker.js');

const subscribe = (callback) => {
  worker.port.onmessage = (event) => {
    if (event.data.type === 'STATE_UPDATED') {
      callback();
    }
  };
  worker.port.start();
  return () => (worker.port.onmessage = null);
};

const getSnapshot = () => worker.port.state;

const useSharedWorkerState = () => useSyncExternalStore(subscribe, getSnapshot);

export default useSharedWorkerState;
This code creates a connection to the shared worker and sets up a function to use React's useSyncExternalStore to manage state synchronization.
// In your React component
import useSharedWorkerState from './main'; // Assume main.js is in the same directory

const MyComponent = () => {
  const state = useSharedWorkerState();

  // Your component logic... to update worker state
  worker.port.postMessage({ type: 'SET_STATE', payload: { /* New State Here */ } });

  return (
    <div>
      {/* Render your component using the state from the worker */}
    </div>
  );
};

export default MyComponent;
Example of a React component using the custom hook useSharedWorkerState to get shared state and send updates back to the worker.