<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Naimur Rahman - Senior Frontend Engineer]]></title><description><![CDATA[Experienced Senior Frontend Engineer, adept in full-stack development, who loves crafting innovative solutions and is always up for a coding challenge.]]></description><link>https://naimur.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 05:35:36 GMT</lastBuildDate><atom:link href="https://naimur.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[BroadcastChannel API: Sending Messages Between Tabs]]></title><description><![CDATA[Why Tab Communication in Web Browser Matters
Communicating between different tabs or windows in a web browser is super important for many reasons. Imagine you have several open tabs while shopping online. You put an item in your cart in one tab, and ...]]></description><link>https://naimur.dev/broadcastchannel-api</link><guid isPermaLink="true">https://naimur.dev/broadcastchannel-api</guid><category><![CDATA[communication]]></category><category><![CDATA[Real Time]]></category><category><![CDATA[Browsers]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[BroadcastChannel]]></category><dc:creator><![CDATA[Naimur Rahman]]></dc:creator><pubDate>Wed, 06 Sep 2023 14:03:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694004638120/256e970f-17da-475d-8aa2-e20c4e872202.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-why-tab-communication-in-web-browser-matters">Why Tab Communication in Web Browser Matters</h2>
<p>Communicating between different tabs or windows in a web browser is super important for many reasons. Imagine you have several open tabs while shopping online. You put an item in your cart in one tab, and you want all the other tabs to know about it instantly. That's one of the reasons we need this kind of communication. Also, think about logging into a website like your bank account. If we log out in one tab, we'd want to be logged out in all the other tabs, too to keep everything safe. It's like making sure you lock all the doors when leaving your house. So, it's not just convenient; it also makes the web safer and more efficient for us.</p>
<h2 id="heading-what-is-the-broadcast-channel-api">What is the Broadcast Channel API?</h2>
<p>The Broadcast Channel API is like a special communication tool for web browsers. It allows different tabs or windows in our browser to talk to each other. It's a way for them to share information instantly. Think of it as a secret chat system just for our browser. It helps web apps work together and stay in sync, making our online experience smoother.</p>
<h2 id="heading-how-broadcast-channel-api-works">How Broadcast Channel API works</h2>
<p>Here's how it works in simple terms:</p>
<ol>
<li><p><strong>Create a Channel</strong>: We create a channel with a specific name, like <code>cart_channel</code></p>
</li>
<li><p><strong>Send Messages</strong>: In one tab, we can send a message (like "I added a new item to the cart!") to the <code>cart_channel</code></p>
</li>
<li><p><strong>Other Tabs Listen</strong>: All the other open tabs also tuned into the <code>cart_channel</code> can hear this message.</p>
</li>
<li><p><strong>Instant Updates</strong>: So, when we add something to our cart in one tab, all the other tabs can instantly update to show the same thing. It's like magic!</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694008679571/ec49b41b-57be-49fd-9e49-c72d3608908d.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-step-by-step-guide-using-broadcast-channel-api">Step-by-Step Guide: Using Broadcast Channel API</h2>
<p>Now that we know how this API works, In this section we'll walk through the process of using the Broadcast Channel API step by step. In this article, we will use the <strong>Cart</strong> Example.</p>
<h4 id="heading-step-1-create-a-broadcast-channel">Step 1: Create a Broadcast Channel</h4>
<p>To get started, create a javascript file <code>broadcast.js</code> and create a new instance of Broadcast Channel API. This channel serves as the communication medium. We can give it a specific name, like 'chat_channel'.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cartChannel = <span class="hljs-keyword">new</span> BroadcastChannel(<span class="hljs-string">'cart_channel'</span>);
</code></pre>
<p>Here we created a new Broadcast Channel named <code>cart_channel</code> using <code>new BroadcastChannel('cart_channel')</code>. This sets up the communication channel.</p>
<h4 id="heading-step-2-send-cart-updates-to-tabs">Step 2: Send Cart Updates to Tabs</h4>
<p>We can send cart updates through the Broadcast Channel, ensuring that all tabs or windows are synchronized. For instance, when a user adds an item to their cart, we can broadcast the update.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addToCart</span>(<span class="hljs-params">itemName</span>) </span>{
    <span class="hljs-comment">// do actions when adding items to cart</span>
    <span class="hljs-keyword">const</span> updateMessage = <span class="hljs-string">`Added "<span class="hljs-subst">${itemName}</span>" to the cart.`</span>;
    updateCartUI(updateMessage);
    cartChannel.postMessage(updateMessage);
}
</code></pre>
<p>In this step:</p>
<ul>
<li><p>We define a function <code>addToCart</code> takes the <code>itemName</code> as a parameter.</p>
</li>
<li><p>Inside the function, we update our active tab UI by calling <code>updateCartUI(updateMessage)</code> and send a message to other tabs connected to the <code>cart_channel</code> using <code>cartChannel.postMessage(updateMessage)</code> and tell them to update themselves with a new cart item.</p>
</li>
</ul>
<h4 id="heading-step-3-receive-cart-updates">Step 3: Receive Cart Updates</h4>
<p>To receive cart updates in other tabs or windows, set up an event listener for the Broadcast Channel. When a cart update is broadcasted, this listener will capture it.</p>
<pre><code class="lang-javascript">cartChannel.addEventListener(<span class="hljs-string">'message'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> receivedUpdate = event.data;
    updateCartUI(receivedUpdate);
});
</code></pre>
<p>In this step:</p>
<ul>
<li><p>We added an event listener to the <code>cart_channel</code> using <code>cartChannel.addEventListener('message', (event) =&gt; { ... })</code>.</p>
</li>
<li><p>When a cart update is received, the event handler function is called with the received data <code>event.data</code>, which contains the update message.</p>
</li>
<li><p>We can then call a function like <code>updateCartUI</code> to update the cart UI with the received update.</p>
</li>
</ul>
<p>Now our <code>broadcast.js</code> file should look like this</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Step 1: Create a Broadcast Channel</span>
<span class="hljs-keyword">const</span> cartChannel = <span class="hljs-keyword">new</span> BroadcastChannel(<span class="hljs-string">"cart_channel"</span>);

<span class="hljs-comment">// Step 2: Send Cart Updates</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addToCart</span>(<span class="hljs-params">itemName</span>) </span>{
  <span class="hljs-keyword">const</span> updateMessage = <span class="hljs-string">`Added "<span class="hljs-subst">${itemName}</span>" to the cart.`</span>;
  updateCartUI(updateMessage);
  cartChannel.postMessage(updateMessage);
}

<span class="hljs-comment">// Step 3: Receive Cart Updates</span>
cartChannel.addEventListener(<span class="hljs-string">"message"</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> receivedUpdate = event.data;
  updateCartUI(receivedUpdate);
});

<span class="hljs-comment">// Function to update the cart UI</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateCartUI</span>(<span class="hljs-params">updateMessage</span>) </span>{
  <span class="hljs-keyword">const</span> cartElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"cart"</span>);
  <span class="hljs-keyword">const</span> newItemElement = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"p"</span>);
  newItemElement.textContent = updateMessage;
  cartElement.appendChild(newItemElement);
}
</code></pre>
<h2 id="heading-live-example-and-testing">Live Example and Testing</h2>
<p>To test this real-time cart updating application follow these steps:</p>
<ol>
<li><p>Open <a target="_blank" href="https://real-time-cart-update.naimur.repl.co/">this URL</a> in two or three tabs on your browser.</p>
</li>
<li><p>Click on any button <em>(for example</em> <code>Add Product A to Cart</code><em>)</em> to add an item to the cart</p>
</li>
<li><p>Go to another tab, you should see the cart is added on UI here as well in <strong>real-time</strong>. You can check this on another browser window as well.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694007558887/8ccc9232-5e0c-42db-8df1-a8402c95aee3.gif" alt="Example" class="image--center mx-auto" /></p>
<h2 id="heading-helpful-links">Helpful Links</h2>
<p><strong>Live URL</strong> 👉 <a target="_blank" href="https://real-time-cart-update.naimur.repl.co/">https://real-time-cart-update.naimur.repl.co/</a></p>
<p><strong>Full code on Github</strong> 👉 <a target="_blank" href="https://github.com/nsourov/broadcast-api">https://github.com/nsourov/broadcast-api</a></p>
<p><strong>BroadcastChannel API MDN documentation</strong> 👉 <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API">https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API</a></p>
]]></content:encoded></item><item><title><![CDATA[Building Offline-Ready Webpage with Service Worker and Cache Storage]]></title><description><![CDATA[Why We Need Offline Web Pages
Sometimes, our internet connection isn't reliable or completely absent. In those moments, we still want to use websites and apps. This is where offline web pages come in handy. They allow us to access content even when w...]]></description><link>https://naimur.dev/building-offline-ready-webpage-with-service-worker-and-cache-storage</link><guid isPermaLink="true">https://naimur.dev/building-offline-ready-webpage-with-service-worker-and-cache-storage</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Service Workers]]></category><dc:creator><![CDATA[Naimur Rahman]]></dc:creator><pubDate>Tue, 05 Sep 2023 10:12:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693908546400/2bc7e111-a5c7-4750-86fd-94d69779ce69.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-why-we-need-offline-web-pages">Why We Need Offline Web Pages</h2>
<p>Sometimes, our internet connection isn't reliable or completely absent. In those moments, we still want to use websites and apps. This is where offline web pages come in handy. They allow us to access content even when we're not online.</p>
<h2 id="heading-introducing-service-workers-and-cache-storage">Introducing Service Workers and Cache Storage</h2>
<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"><strong>Service Workers</strong></a> are like web helpers. It work behind the scenes to make offline web pages possible. It can save website stuff (like pictures, fonts and other assets) on our device so we can see them even without the internet. It also control what our web page does when it's online.</p>
<p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage"><strong>Cache Storage</strong></a> is like a storage room for web things. It keeps all the website stuff we might need, organised neatly. Service Workers can go there and grab what's needed for page to load offline. So, when we're not online, we still get to see and use web pages.</p>
<p>Let's explore how to make a webpage available offline by doing some simple coding. We'll save an HTML file and an image so that users can still see them, even when they are not connected to the internet.</p>
<p><strong>Step 1: Getting Started</strong> First, Let's create a folder for our project and put main HTML file <code>index.html</code> and the image we want to use <code>cat.jpeg</code> inside it.</p>
<p><strong>Step 2: Registering the Service Worker</strong> Now, let's register the Service Worker in <code>index.html</code> file. Place the following code:</p>
<pre><code class="lang-js">&lt;!DOCTYPE html&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Document<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hi There!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./cat.jpeg"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"300"</span> /&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">registerServiceWorker</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">if</span> (<span class="hljs-string">"serviceWorker"</span> <span class="hljs-keyword">in</span> navigator) {
          <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">const</span> registration = <span class="hljs-keyword">await</span> navigator.serviceWorker.register(
              <span class="hljs-string">"sw.js"</span>
            );
            <span class="hljs-built_in">console</span>.log(
              <span class="hljs-string">"Service Worker registered with scope:"</span>,
              registration.scope
            );
          } <span class="hljs-keyword">catch</span> (error) {
            <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Service Worker registration failed:"</span>, error);
          }
        }
      }

      registerServiceWorker();
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre>
<p>In this code we check if the browser supports Service Workers.</p>
<p><strong>Step 3: Writing the Service Worker Code</strong> Now, let's create a JavaScript file called <code>sw.js</code> in project folder. This file will contain the code for Service Worker.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> cacheName = <span class="hljs-string">"offline-cache-v1"</span>;
<span class="hljs-keyword">const</span> cacheUrls = [<span class="hljs-string">"index.html"</span>, <span class="hljs-string">"cat.jpeg"</span>];

<span class="hljs-comment">// Installing the Service Worker</span>
self.addEventListener(<span class="hljs-string">"install"</span>, <span class="hljs-keyword">async</span> (event) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> cache = <span class="hljs-keyword">await</span> caches.open(cacheName);
    <span class="hljs-keyword">await</span> cache.addAll(cacheUrls);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Service Worker installation failed:"</span>, error);
  }
});

<span class="hljs-comment">// Fetching resources</span>
self.addEventListener(<span class="hljs-string">"fetch"</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.respondWith(
    (<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">const</span> cache = <span class="hljs-keyword">await</span> caches.open(cacheName);

      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> cachedResponse = <span class="hljs-keyword">await</span> cache.match(event.request);
        <span class="hljs-keyword">if</span> (cachedResponse) {
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"cachedResponse: "</span>, event.request.url);
          <span class="hljs-keyword">return</span> cachedResponse;
        }

        <span class="hljs-keyword">const</span> fetchResponse = <span class="hljs-keyword">await</span> fetch(event.request);
        <span class="hljs-keyword">if</span> (fetchResponse) {
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"fetchResponse: "</span>, event.request.url);
          <span class="hljs-keyword">await</span> cache.put(event.request, fetchResponse.clone());
          <span class="hljs-keyword">return</span> fetchResponse;
        }
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Fetch failed: "</span>, error);
        <span class="hljs-keyword">const</span> cachedResponse = <span class="hljs-keyword">await</span> cache.match(<span class="hljs-string">"index.html"</span>);
        <span class="hljs-keyword">return</span> cachedResponse;
      }
    })()
  );
});
</code></pre>
<p>THere's what's happening in the code:</p>
<ul>
<li><p>We give a name to our cache (cacheName) and list the URLs (cacheUrls) we want to store for offline use.</p>
</li>
<li><p>In the "install" part, we prepare our cache and add the URLs to it.</p>
</li>
<li><p>We open the cache and attempt to match the request with the cached responses.</p>
</li>
<li><p>If a cached response is found, it's returned. If not, we fetch the resource from the network, cache it for future use, and return the network response.</p>
</li>
<li><p>In case of any errors during the fetch process, we handle it by returning a cached version of "index.html" to ensure the user still sees something.</p>
</li>
</ul>
<p><strong>Step 4: Testing our Offline-Friendly webpage</strong> To check if the page works offline:</p>
<ul>
<li><p>Open the page while the device is online to make sure it loads correctly, including the image.</p>
</li>
<li><p>Disconnect from the internet (turn off Wi-Fi or unplug network cable).</p>
</li>
<li><p>Reload the page. We should still see the page, including the image, even though there's no internet.</p>
</li>
</ul>
<p>We can also test from the chrome browser, here's the steps:</p>
<ul>
<li><p>Open the page while the device is online</p>
</li>
<li><p>Open devtools in chrome browser and go to the <code>Application</code> tab</p>
</li>
<li><p>Click on <code>Service Workers</code> from the sidebar and check the <code>Offline</code> option</p>
</li>
<li><p>Reload the page and we can see the contents loading offline</p>
</li>
</ul>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tfjbg2k6kgv0cgx4dr2m.png" alt="Cate image" /></p>
<p>We've now created a webpage that can work offline using Service Workers. This technique can be expanded to store more things and make websites robust even when there's no internet.</p>
<p>Full Code 👉 <a target="_blank" href="https://github.com/nsourov/offline-web-page">https://github.com/nsourov/offline-web-page</a></p>
]]></content:encoded></item></channel></rss>