DEV Community

sanketmunot
sanketmunot

Posted on

Implementing a Message-Driven Architecture for Live IPL Scores in a Chrome Extension

As discussed in the previous architecture flow, our extension relies on message passing between the background worker and the content script. The background script fetches live scores from an external API, while the content script renders the data into the DOM of the active tab. Let’s break down how this works step by step:

Flow diagram

Step-by-Step Flow

  1. Initialization

    Upon loading, the content script checks whether the scoreboard display is enabled. It sends an initialization message ("init") to the background script to determine if it should start fetching and displaying scores.

    const init = async () => {
      let { isEnabled } = await chrome.storage.sync.get("isEnabled");
      chrome.runtime.sendMessage({
      action: "init",
      isEnabled: isEnabled,
      });
    };
    init();
    
  2. Fetching Live Scores

    The background script listens for messages, and when triggered, it begins polling an API every 5 seconds to fetch live IPL scores.

    chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
      const { isEnabled } = message;
      if (message.action === "init" && isEnabled) {
      getLatestScoresAndRender();
      }
      if (message.action === "toggleLogging") {
      if (isEnabled) {
        startCricket(); // Runs getLatestScoresAndRender every 5 seconds
      } else {
        stopCricket();
      }
      }
    });
    
  3. Rendering Data

    When the background script receives the latest scores, it sends the data to the active tab's content script, which then updates the DOM dynamically with the latest match data.

    //background.js
    chrome.tabs.sendMessage(tabId, { action: "polling", data: allIplMatches });
    

    And in the content script:

    chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
      if (message.action === "polling") {
      // Use match data from the message to update the DOM
      }
    });
    
  4. User Interaction (Toggle On/Off)

    Users can toggle the scoreboard on or off with a single click. This toggle sends a "toggleLogging" message to the background script, which starts or stops the polling accordingly.

    chrome.runtime.onMessage.addListener(function (message) {
      if (message.action === "toggleLogging") {
      if (isEnabled) {
        startCricket();
      } else {
        stopCricket();
      }
      }
    });
    

Yes we had to use react for our popup, here's how -

Image description

We need to specify an HTML file in the manifest that will serve as our extension's popup. For the extension's control interface, we developed it as a React component and linked the corresponding script in the index.html.

  "action": {
    "default_popup": "index.html"
  }
Enter fullscreen mode Exit fullscreen mode
  <script src="bundle.js"></script> //bundle.js is the built react file
Enter fullscreen mode Exit fullscreen mode

While at it you can also give a read to Medium article from Neha Malvia which explains bits of repository

Conclusion

By leveraging Chrome's message-passing APIs, we split the responsibilities between background workers (handling API requests) and content scripts (handling DOM updates). This event-driven architecture ensures smooth, real-time updates across multiple tabs, creating a seamless user experience without unnecessary refreshes or interruptions.

This modular approach allows the extension to be highly efficient, responsive, and user-friendly, with the ability to toggle the score display on or off easily.


Dont miss the extras webpack for chrome extension where we defined a webpack config to streamline our build.

Top comments (0)