<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: javediqbal8381</title>
    <description>The latest articles on DEV Community by javediqbal8381 (@javediqbal8381).</description>
    <link>https://dev.to/javediqbal8381</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1066039%2F816bf156-b894-431c-8875-e90ce8dbc3b7.jpeg</url>
      <title>DEV Community: javediqbal8381</title>
      <link>https://dev.to/javediqbal8381</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/javediqbal8381"/>
    <language>en</language>
    <item>
      <title>Annotation Tool</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Tue, 02 Dec 2025 19:15:33 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/annotation-tool-h14</link>
      <guid>https://dev.to/javediqbal8381/annotation-tool-h14</guid>
      <description>&lt;p&gt;If you ever need to quickly point out bugs, highlight sections, or add notes to an image — try this simple Image Annotation Tool!&lt;br&gt;
You can take a screenshot directly, upload an image from your computer, or even paste a URL. Super easy and super handy 🎯&lt;/p&gt;

&lt;p&gt;Give it a try: &lt;a href="https://www.justinbrowser.com/tools/image-annotator" rel="noopener noreferrer"&gt;https://www.justinbrowser.com/tools/image-annotator&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Stay Updated with the Latest Tech News 📰</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Wed, 05 Nov 2025 12:07:49 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/stay-updated-with-the-latest-tech-news-4f44</link>
      <guid>https://dev.to/javediqbal8381/stay-updated-with-the-latest-tech-news-4f44</guid>
      <description>&lt;p&gt;I’ve added a new page where you can find the latest updates from the tech world.&lt;/p&gt;

&lt;p&gt;If you love keeping up with new technologies, trends, and innovations, this page brings it all together in one place.&lt;/p&gt;

&lt;p&gt;Check it out here  &lt;a href="https://www.justinbrowser.com/latest-tech-news" rel="noopener noreferrer"&gt;justinbrowser news&lt;/a&gt;&lt;/p&gt;

</description>
      <category>news</category>
      <category>techtalks</category>
      <category>ai</category>
    </item>
    <item>
      <title>🎨 Build Layouts Visually in Seconds — Meet the Layout Builder by JustinBrowser</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Fri, 24 Oct 2025 09:43:00 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/build-layouts-visually-in-seconds-meet-the-layout-builder-by-justinbrowser-4pf3</link>
      <guid>https://dev.to/javediqbal8381/build-layouts-visually-in-seconds-meet-the-layout-builder-by-justinbrowser-4pf3</guid>
      <description>&lt;p&gt;Have you ever wished you could design layouts by just drawing boxes — and instantly get the JSX + Tailwind or HTML + CSS code?&lt;br&gt;
Now you can. 🚀&lt;/p&gt;

&lt;p&gt;👉 Try it here: &lt;a href="https://www.justinbrowser.com/tools/layout-builder" rel="noopener noreferrer"&gt;Layout Builder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>design</category>
      <category>uidesign</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding Chrome Extensions: A Developer's Guide to Manifest V3</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Wed, 22 Oct 2025 09:10:33 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/understanding-chrome-extensions-a-developers-guide-to-manifest-v3-233l</link>
      <guid>https://dev.to/javediqbal8381/understanding-chrome-extensions-a-developers-guide-to-manifest-v3-233l</guid>
      <description>&lt;h1&gt;
  
  
  Understanding Chrome Extensions: A Developer's Guide to Manifest V3
&lt;/h1&gt;

&lt;p&gt;Chrome extensions have become essential tools that enhance browser functionality for millions of users worldwide. As a developer, understanding how they work under the hood is crucial for building powerful, secure, and performant extensions. In this comprehensive guide, we'll dive deep into Chrome extension architecture, the Manifest V3 specification, and everything you need to know to publish your extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ Extension Architecture: The Core Components
&lt;/h2&gt;

&lt;p&gt;Every Chrome extension is built from several key components that work together seamlessly:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Manifest File (manifest.json)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The manifest is the blueprint of your extension - a JSON configuration file that must reside in the root directory. It's the first thing Chrome reads and contains metadata, permissions, and component declarations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required fields:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Extension"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Common additional fields:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Awesome Extension"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A brief description of what your extension does"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"icons"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icons/icon16.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"48"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icons/icon48.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"128"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icons/icon128.png"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"default_popup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"popup.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"default_icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icons/icon48.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"default_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Click me!"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service_worker"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"background.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content_scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://*/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://*/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"content.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"css"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"styles.css"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"storage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"tabs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"activeTab"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host_permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://api.example.com/*"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Service Worker (Background Script)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In Manifest V3, the persistent background page has been replaced with service workers. This is a &lt;strong&gt;major architectural change&lt;/strong&gt; designed to improve performance and security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key characteristics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs in the background only when needed (event-driven)&lt;/li&gt;
&lt;li&gt;No access to the DOM&lt;/li&gt;
&lt;li&gt;Automatically terminates after 30 seconds of inactivity&lt;/li&gt;
&lt;li&gt;Restarts when an event is triggered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example service worker:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// background.js&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onInstalled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Extension installed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;initialized&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Listen for tab updates&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onUpdated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;changeInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;changeInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tab loaded:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Listen for messages&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Process data&lt;/span&gt;
    &lt;span class="nf"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Response from background&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Required for async sendResponse&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Content Scripts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Content scripts run in the context of web pages and can interact with the DOM. They're injected into pages matching patterns defined in the manifest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two ways to inject content scripts:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Declarative (via manifest):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content_scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"content.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"run_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"document_idle"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Programmatic (via scripting API):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In service worker&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClicked&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scripting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeScript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Or inject a function&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;injectedFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lightblue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scripting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeScript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;injectedFunction&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Popup / Action UI&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The popup is an HTML page that appears when users click your extension icon in the toolbar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- popup.html --&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;My Extension&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"actionBtn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Do Something&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"popup.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// popup.js&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;actionBtn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;currentWindow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;performAction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Response:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📡 Communication Patterns
&lt;/h2&gt;

&lt;p&gt;One of the most critical aspects of extension development is understanding how different components communicate with each other.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;One-time Messages&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;From content script to service worker:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// content.js&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Response:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;From service worker to content script:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// background.js&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;updateUI&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Response:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;From popup to service worker:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// popup.js&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Long-lived Connections&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For multiple messages between components, use ports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// content.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-channel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;init&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Received:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// background.js&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Connected:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Message received:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;acknowledged&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Communication with Web Pages&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Content scripts and web pages share the DOM but have isolated JavaScript contexts. Use &lt;code&gt;window.postMessage&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// content.js&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FROM_PAGE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Message from page:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Forward to service worker if needed&lt;/span&gt;
    &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// webpage.js&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FROM_PAGE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from webpage!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔐 Permissions System
&lt;/h2&gt;

&lt;p&gt;Permissions in Manifest V3 are more granular and security-focused. There are four types:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Regular Permissions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;API permissions that don't require host access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"storage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;chrome.storage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;API&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"tabs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Limited&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;tabs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;API&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;access&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"activeTab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Access&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;tab&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(requires&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;gesture)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"contextMenus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;context&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;menu&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;items&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"notifications"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Show&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;notifications&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"scripting"&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Execute&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;scripts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;programmatically&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Host Permissions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Access to specific URLs or patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host_permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://api.example.com/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://*.google.com/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;all_urls&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Access&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;URLs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sparingly!)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Optional Permissions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Requested at runtime rather than install time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"optional_permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"downloads"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bookmarks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"optional_host_permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://*/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request them in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;enableFeature&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;granted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;downloads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;origins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;granted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Permission granted!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Content Script Matches&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Separate from host_permissions - controls where content scripts inject:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content_scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"content.js"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚡ Manifest V3 Key Changes
&lt;/h2&gt;

&lt;p&gt;If you're migrating from V2 or starting fresh, here are the critical changes:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Background Pages → Service Workers&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Manifest V2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;persistent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Manifest V3&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;service_worker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;// Optional: enables ES modules&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Host Permissions Separation&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Manifest V2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;permissions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tabs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://*/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Manifest V3&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;permissions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tabs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;host_permissions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://*/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;executeScript Migration&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Manifest V2&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;document.body.style.backgroundColor = "red"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Manifest V3&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scripting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeScript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tabId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;webRequest → declarativeNetRequest&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For content blocking and request modification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"declarativeNetRequest"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"declarative_net_request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rule_resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ruleset_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rules.json"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;No Remote Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;All code must be bundled with the extension. External scripts from CDNs are &lt;strong&gt;no longer allowed&lt;/strong&gt; for security reasons.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 What You Can Do Without Permissions
&lt;/h2&gt;

&lt;p&gt;Some Chrome APIs don't require permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;chrome.runtime&lt;/code&gt; (messaging, extension info)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chrome.i18n&lt;/code&gt; (internationalization)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chrome.action&lt;/code&gt; (basic toolbar icon interaction)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;window&lt;/code&gt; and &lt;code&gt;document&lt;/code&gt; APIs in content scripts&lt;/li&gt;
&lt;li&gt;Standard web APIs (fetch, localStorage in content scripts)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Publishing to Chrome Web Store
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Prepare Your Extension&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test thoroughly&lt;/strong&gt; - Load unpacked in &lt;code&gt;chrome://extensions/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create assets:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;128x128 icon (required)&lt;/li&gt;
&lt;li&gt;440x280 or 920x680 screenshots (required)&lt;/li&gt;
&lt;li&gt;1280x800 promotional image (optional)&lt;/li&gt;
&lt;li&gt;Privacy policy (if handling user data)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Package your extension:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Create a zip file with manifest.json at root&lt;/span&gt;
   zip &lt;span class="nt"&gt;-r&lt;/span&gt; extension.zip &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="s2"&gt;"*.git*"&lt;/span&gt; &lt;span class="s2"&gt;"node_modules/*"&lt;/span&gt; &lt;span class="s2"&gt;".DS_Store"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Register as Developer&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://chrome.google.com/webstore/devconsole" rel="noopener noreferrer"&gt;Chrome Web Store Developer Dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pay $5 one-time registration fee&lt;/li&gt;
&lt;li&gt;Enable 2-factor authentication (required as of 2024)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3: Upload Extension&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click "New Item"&lt;/li&gt;
&lt;li&gt;Upload your zip file&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fill out the Store Listing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Description&lt;/strong&gt; - Clear explanation of functionality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Category&lt;/strong&gt; - Choose appropriate category&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language&lt;/strong&gt; - Target language(s)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshots&lt;/strong&gt; - At least 1, up to 5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Privacy Tab:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Purpose&lt;/strong&gt; - Declare extension's purpose&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permission Justifications&lt;/strong&gt; - Explain why each permission is needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Usage&lt;/strong&gt; - Disclose any data collection&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Distribution Tab:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visibility&lt;/strong&gt; - Public, Unlisted, or Private&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regions&lt;/strong&gt; - Select target countries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt; - Free or paid&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4: Submit for Review&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Review times vary but &lt;strong&gt;most extensions are reviewed within 3 days&lt;/strong&gt;. You'll receive an email notification once reviewed.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Publishing Options:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Public:&lt;/strong&gt; Available to everyone in Chrome Web Store&lt;br&gt;
&lt;strong&gt;Unlisted:&lt;/strong&gt; Only accessible via direct link&lt;br&gt;
&lt;strong&gt;Private:&lt;/strong&gt; Only for users in your domain/organization&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 5: Update Your Extension&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To publish updates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Increment version number in manifest.json&lt;/li&gt;
&lt;li&gt;Upload new zip file&lt;/li&gt;
&lt;li&gt;Submit for review&lt;/li&gt;
&lt;li&gt;Can use &lt;strong&gt;percentage rollout&lt;/strong&gt; to gradually release to users&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Programmatic Publishing (CI/CD)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can automate publishing using the Chrome Web Store API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Using chrome-webstore-upload npm package&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;chromeWebstoreUpload&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chrome-webstore-upload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;chromeWebstoreUpload&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;extensionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-extension-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REFRESH_TOKEN&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myZipFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./extension.zip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uploadExisting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myZipFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ Development Tips &amp;amp; Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use ES Modules&lt;/strong&gt; - Set &lt;code&gt;"type": "module"&lt;/code&gt; in background config&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle Service Worker Lifecycle&lt;/strong&gt; - Store state in &lt;code&gt;chrome.storage&lt;/code&gt;, not variables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimize Permissions&lt;/strong&gt; - Only request what you absolutely need&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test on Multiple Chrome Versions&lt;/strong&gt; - Use beta/dev channels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor Performance&lt;/strong&gt; - Service workers should be lightweight&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Error Handling&lt;/strong&gt; - Always check &lt;code&gt;chrome.runtime.lastError&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Promises&lt;/strong&gt; - Modern Chrome APIs support promises in the &lt;code&gt;chrome.*&lt;/code&gt; namespace
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Modern promise-based approach&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎯 Common Pitfalls to Avoid
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;❌ Using &lt;code&gt;localStorage&lt;/code&gt; in service workers (not available)&lt;/li&gt;
&lt;li&gt;❌ Assuming service worker stays alive indefinitely&lt;/li&gt;
&lt;li&gt;❌ Not returning &lt;code&gt;true&lt;/code&gt; from &lt;code&gt;onMessage&lt;/code&gt; listener for async responses&lt;/li&gt;
&lt;li&gt;❌ Requesting &lt;code&gt;&amp;lt;all_urls&amp;gt;&lt;/code&gt; without justification&lt;/li&gt;
&lt;li&gt;❌ Including unnecessary files in your package&lt;/li&gt;
&lt;li&gt;❌ Not handling permission denials gracefully&lt;/li&gt;
&lt;li&gt;❌ Using &lt;code&gt;eval()&lt;/code&gt; or inline scripts (CSP violation)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🎬 Conclusion
&lt;/h2&gt;

&lt;p&gt;Chrome extensions are powerful tools that can significantly enhance user experience. With Manifest V3, Google has made extensions more secure, performant, and privacy-focused. While the migration from V2 requires some changes, the improved architecture leads to better extensions overall.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/extensions/" rel="noopener noreferrer"&gt;Chrome Extensions Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/extensions/develop/migrate/what-is-mv3" rel="noopener noreferrer"&gt;Manifest V3 Migration Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrome.google.com/webstore/devconsole" rel="noopener noreferrer"&gt;Chrome Web Store Developer Dashboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/GoogleChrome/chrome-extensions-samples" rel="noopener noreferrer"&gt;Extension Samples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;About Me:&lt;/strong&gt; I've developed multiple complex Chrome extensions over the years, ranging from productivity tools to advanced web automation solutions. Through this journey, I've learned the intricacies of extension architecture, performance optimization, and the evolving Chrome extension ecosystem. If you have questions about Chrome extension development, feel free to reach out!&lt;/p&gt;

&lt;p&gt;My site &amp;gt;&amp;gt; &lt;a href="https://justinbrowser.com/" rel="noopener noreferrer"&gt;https://justinbrowser.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>chrome</category>
      <category>extensions</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Simplifying API Testing — Why Sometimes You Don’t Need Postman</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Wed, 22 Oct 2025 04:57:14 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/simplifying-api-testing-why-sometimes-you-dont-need-postman-598g</link>
      <guid>https://dev.to/javediqbal8381/simplifying-api-testing-why-sometimes-you-dont-need-postman-598g</guid>
      <description>&lt;p&gt;API testing is one of the most important, and often repetitive, parts of a developer’s workflow. Whether you’re building a backend, connecting third-party services, or debugging endpoints, being able to test APIs quickly and efficiently can save you a lot of time and frustration.&lt;/p&gt;

&lt;p&gt;You know, Most of us reach for Postman, and for good reason: it’s powerful, feature-rich, and great for teams.&lt;br&gt;
But sometimes, all you need is something simpler, something that just works instantly.&lt;/p&gt;

&lt;p&gt;🧩 The Problem with Heavy Tools&lt;/p&gt;

&lt;p&gt;There are days when I just want to test an endpoint quickly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://api.example.com/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…but opening Postman or Insomnia feels like loading a full IDE just to print “Hello World.”&lt;br&gt;
These tools are excellent for serious workflows, but for small tests, they can feel too heavy.&lt;/p&gt;

&lt;p&gt;So, I built something that scratches this exact itch — a lightweight, browser-based API Tester.&lt;/p&gt;

&lt;p&gt;⚙️ Introducing: API Tester Tool&lt;/p&gt;

&lt;p&gt;What it is:&lt;br&gt;
A browser-based REST API testing tool that lets you send HTTP requests and view responses directly — no installs, no setup.&lt;/p&gt;

&lt;p&gt;You open it, type your endpoint, and hit send. That’s it.&lt;/p&gt;

&lt;p&gt;🔑 Key Features&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Supports all HTTP methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom headers configuration: Add headers in JSON format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request body builder: Easily test POST/PUT/PATCH requests with JSON.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real-time response analysis: Auto-formats JSON responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Color-coded status indicators: Instantly see success, redirects, or errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response time tracking: Get quick performance insights.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request history: Keeps your last 10 requests (with one-click replay).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy or download responses: For quick debugging or sharing.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🆚 Why Use It Over Postman (Sometimes)&lt;/p&gt;

&lt;p&gt;Let’s be honest — this isn’t a Postman killer.&lt;br&gt;
It’s a fast companion for those quick moments when you just want to check something fast.&lt;/p&gt;

&lt;p&gt;🎯 Use Case Examples&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checking your backend endpoints in a hurry.&lt;/li&gt;
&lt;li&gt;Debugging during frontend API integration.&lt;/li&gt;
&lt;li&gt;Testing APIs on a new environment quickly.&lt;/li&gt;
&lt;li&gt;Teaching or demonstrating APIs without installing software.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🌐 Try It Yourself&lt;/p&gt;

&lt;p&gt;You can try the API Tester Tool right now in your browser — no account, no setup, no download.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.justinbrowser.com/tools/api-tester" rel="noopener noreferrer"&gt;Open API Tester Tool&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>testing</category>
      <category>postman</category>
    </item>
    <item>
      <title>Image Related Tools All in one place</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Tue, 30 Sep 2025 19:50:30 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/image-related-tools-all-in-one-place-3m8e</link>
      <guid>https://dev.to/javediqbal8381/image-related-tools-all-in-one-place-3m8e</guid>
      <description>&lt;p&gt;I’ve put all the image-related tools together in one place. Check them out at justinbrowser, you will love it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://justinbrowser.com/tools/image-compressor" rel="noopener noreferrer"&gt;🗜️ Image Compressor – Compress JPG, PNG, WebP&lt;/a&gt;&lt;br&gt;
✂️ &lt;a href="https://justinbrowser.com/tools/crop-image" rel="noopener noreferrer"&gt;Image Cropper – Crop with aspect ratios&lt;/a&gt;&lt;br&gt;
📐 &lt;a href="https://justinbrowser.com/tools/image-resizer" rel="noopener noreferrer"&gt;Image Resizer – Resize or batch resize&lt;/a&gt;&lt;br&gt;
🖊️ &lt;a href="https://justinbrowser.com/tools/image-annotator" rel="noopener noreferrer"&gt;Image Annotator – Add arrows, shapes &amp;amp; text&lt;/a&gt;&lt;br&gt;
🎨 &lt;a href="https://justinbrowser.com/tools/color-extractor" rel="noopener noreferrer"&gt;Color Palette Extractor – Get hex codes from images&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Simple Image Resizer Tool</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Fri, 19 Sep 2025 18:08:52 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/simple-image-resizer-tool-1hn1</link>
      <guid>https://dev.to/javediqbal8381/simple-image-resizer-tool-1hn1</guid>
      <description>&lt;p&gt;Need to resize your images quick? This &lt;a href="https://www.justinbrowser.com/tools/image-resizer" rel="noopener noreferrer"&gt;image resizer&lt;/a&gt; makes it super easy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;br&gt;
Upload &amp;gt;&amp;gt; Just upload your images. Works with JPG, PNG, WebP, and even GIFs.&lt;/p&gt;

&lt;p&gt;Resize &amp;gt;&amp;gt; Choose the size you want in pixels, scale by percentage, or use ready-made presets. You can also keep the aspect ratio so things don’t look stretched.&lt;/p&gt;

&lt;p&gt;Download &amp;gt;&amp;gt; Grab your images one by one or all together in a ZIP. They stay high quality and keep their original names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handy Presets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instagram Post: 1080×1080&lt;/li&gt;
&lt;li&gt;Instagram Story: 1080×1920&lt;/li&gt;
&lt;li&gt;YouTube Thumbnail: 1280×720&lt;/li&gt;
&lt;li&gt;Twitter Banner: 1500×500&lt;/li&gt;
&lt;li&gt;LinkedIn Banner: 1584×396&lt;/li&gt;
&lt;li&gt;Facebook Cover: 820×312&lt;/li&gt;
&lt;li&gt;720p, 1080p, 2K, 4K screen sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it. Upload → Resize → Download. Fast, simple, no fuss.&lt;/p&gt;

&lt;p&gt;Try it out in justinbrowser &amp;gt; &lt;a href="https://www.justinbrowser.com/tools/image-resizer" rel="noopener noreferrer"&gt;https://www.justinbrowser.com/tools/image-resizer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>design</category>
      <category>webdev</category>
      <category>unsplash</category>
    </item>
    <item>
      <title>5 Metrics Every SaaS Business Should Track</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Wed, 17 Sep 2025 05:37:26 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/5-metrics-every-saas-business-should-track-406m</link>
      <guid>https://dev.to/javediqbal8381/5-metrics-every-saas-business-should-track-406m</guid>
      <description>&lt;p&gt;To scale effectively, monitor these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customer Acquisition Cost (CAC)&lt;/strong&gt; – The average cost of acquiring a new customer, including marketing, sales, and onboarding expenses. Lower CAC means more efficient growth.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customer Lifetime Value (CLV)&lt;/strong&gt; – The total revenue a business can expect from a customer throughout their relationship. A higher CLV compared to CAC indicates strong profitability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monthly Recurring Revenue (MRR)&lt;/strong&gt; – Predictable monthly income from subscriptions or contracts. It’s a key metric for measuring SaaS growth and stability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Churn Rate&lt;/strong&gt; – The percentage of customers or revenue lost over a period. A high churn rate signals customer dissatisfaction or poor retention.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Net Promoter Score (NPS)&lt;/strong&gt; – A measure of customer loyalty based on their likelihood to recommend your product. Higher NPS reflects better satisfaction and stronger word-of-mouth growth.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Which KPI do you track most closely?&lt;/p&gt;

</description>
      <category>sass</category>
      <category>startup</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Mastering Regular Expressions with the Regex Tester Tool</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Tue, 16 Sep 2025 13:38:37 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/mastering-regular-expressions-with-the-regex-tester-tool-43pi</link>
      <guid>https://dev.to/javediqbal8381/mastering-regular-expressions-with-the-regex-tester-tool-43pi</guid>
      <description>&lt;p&gt;If you have ever worked with text processing, validation, or search patterns, chances are you have come across regular expressions (regex). They are incredibly powerful but often intimidating, especially when debugging complex patterns.&lt;/p&gt;

&lt;p&gt;That is where the &lt;a href="https://www.justinbrowser.com/tools/regex-tester" rel="noopener noreferrer"&gt;Regex Tester&lt;/a&gt; at justinbrowser&lt;br&gt;
 comes in. It is a clean, efficient, and developer-focused tool designed to make working with regex faster, easier, and more reliable.&lt;/p&gt;

&lt;p&gt;Why Regex Testing Matters&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regular expressions are used everywhere:&lt;/li&gt;
&lt;li&gt;Validating email addresses or phone numbers&lt;/li&gt;
&lt;li&gt;Extracting data from logs&lt;/li&gt;
&lt;li&gt;Searching text in editors and IDEs&lt;/li&gt;
&lt;li&gt;Defining parsing rules for scripts and automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the tricky part is getting the pattern right. A small mistake in a regex can lead to mismatched results or even missed data entirely. Having a tool that shows real-time feedback can save hours of trial and error.&lt;/p&gt;

&lt;p&gt;Key Features of Regex Tester&lt;/p&gt;

&lt;p&gt;✅ Real-Time Pattern Testing&lt;br&gt;
Type your regex and instantly see which parts of your input match. No waiting, no guesswork.&lt;br&gt;
✅ Match Highlighting&lt;br&gt;
Matched strings are highlighted, making it easy to spot exactly what’s being captured.&lt;br&gt;
✅ Common Patterns Library&lt;br&gt;
From email validation to date formats, you can quickly grab and test popular regex snippets.&lt;br&gt;
✅ Group Capturing&lt;br&gt;
Visualize capture groups to understand how your regex is breaking down text.&lt;br&gt;
✅ Pattern Validation&lt;br&gt;
Ensure your regex is syntactically correct before putting it into production code.&lt;/p&gt;

&lt;p&gt;Who Is It For?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developers fine-tuning search or validation logic.&lt;/li&gt;
&lt;li&gt;Data analysts parsing logs or extracting structured information.&lt;/li&gt;
&lt;li&gt;Students and learners practicing regex syntax with immediate feedback.&lt;/li&gt;
&lt;li&gt;Automation engineers writing parsing rules for scripts and pipelines.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pro Tips for Using Regex Tester&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test with varied input – Don’t just test with “happy path” data; include edge cases.&lt;/li&gt;
&lt;li&gt;Use capture groups wisely – They’re powerful for extracting structured data.&lt;/li&gt;
&lt;li&gt;Validate with examples – Run the regex against multiple strings to ensure it works universally.&lt;/li&gt;
&lt;li&gt;Save common patterns – The built-in library helps, but you can also maintain your own snippets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Regex doesn’t have to be scary. With the Regex Tester on justinbrowser.com, you can experiment, debug, and perfect your patterns with confidence. Whether you’re building data extraction rules, validating input fields, or parsing complex text, this tool helps you see exactly what’s happening in real time.&lt;/p&gt;

&lt;p&gt;👉 Try it out today at &lt;a href="https://www.justinbrowser.com/tools/regex-tester" rel="noopener noreferrer"&gt;justinbrowser&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;

</description>
      <category>regex</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Best Free, Fast, simple Online API Testing Tool for Developers and QA Engineers</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Thu, 11 Sep 2025 15:17:37 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/the-best-free-fast-simple-online-api-testing-tool-for-developers-and-qa-engineers-24kp</link>
      <guid>https://dev.to/javediqbal8381/the-best-free-fast-simple-online-api-testing-tool-for-developers-and-qa-engineers-24kp</guid>
      <description>&lt;p&gt;If you’re building APIs, debugging integrations, or validating endpoints, you know how important a fast and reliable testing tool is. That’s why I built another simple tool in &lt;a href="https://www.justinbrowser.com/tools/api-tester" rel="noopener noreferrer"&gt;JustinBrowser&lt;/a&gt;, which can save your time if you need some quick API testing.&lt;/p&gt;

&lt;p&gt;A powerful, browser-based API testing tool that helps developers and QA engineers test RESTful APIs instantly.&lt;/p&gt;

&lt;p&gt;Unlike bulky desktop apps, API Tester runs directly in your browser — no downloads, no sign-ups, no hidden costs. Just open the tool and start testing your APIs in seconds.&lt;/p&gt;

&lt;p&gt;Why Use this API Request Tester Instead of Postman or Other Tools?&lt;/p&gt;

&lt;p&gt;Many developers rely on Postman or heavy desktop apps for API testing. But if you need something fast, lightweight, and private, API Tester is the perfect alternative:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;100% browser-based (no installation required).&lt;/li&gt;
&lt;li&gt;Free to use with no hidden limitations.&lt;/li&gt;
&lt;li&gt;No account required — start testing right away.&lt;/li&gt;
&lt;li&gt;Built for speed, simplicity, and privacy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these features, API Tester is an ideal choice for developers, testers, freelancers, and QA teams who want an easy-to-use Postman alternative.&lt;/p&gt;

&lt;p&gt;Key Features of API Tester&lt;/p&gt;

&lt;p&gt;✅ Support for all HTTP methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)&lt;br&gt;
✅ Custom headers &amp;amp; authentication tokens (e.g., JWT, Bearer tokens)&lt;br&gt;
✅ JSON request body builder for sending raw data&lt;br&gt;
✅ Real-time response analysis with formatted output&lt;br&gt;
✅ Color-coded status codes (2xx, 4xx, 5xx) for quick debugging&lt;br&gt;
✅ Response time tracking to check API performance&lt;br&gt;
✅ Request history with one-click replay&lt;br&gt;
✅ Copy &amp;amp; download response data&lt;br&gt;
✅ Automatic JSON formatting for better readability&lt;/p&gt;

&lt;p&gt;🛠 Best Practices for Using API Tester&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start simple – test your API with a GET request to ensure it’s live.&lt;/li&gt;
&lt;li&gt;Use headers – add Content-Type or Authorization headers to test protected APIs.&lt;/li&gt;
&lt;li&gt;Track performance – use response time data to spot slow endpoints.&lt;/li&gt;
&lt;li&gt;Debug faster – reproduce test cases with one-click history replay.&lt;/li&gt;
&lt;li&gt;Test error handling – try invalid requests to see how your API responds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🔒 Security &amp;amp; Privacy First&lt;/p&gt;

&lt;p&gt;Your API requests stay 100% private. API Tester processes everything in your browser — no servers, no logs, no tracking. This makes it safe to test APIs with authentication tokens, private endpoints, and sensitive data.&lt;/p&gt;

&lt;p&gt;💡 Who Should Use API Tester?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers – for building and debugging APIs quickly.&lt;/li&gt;
&lt;li&gt;QA Engineers – for validating API responses during testing.&lt;/li&gt;
&lt;li&gt;Freelancers – for client projects without installing heavy tools.&lt;/li&gt;
&lt;li&gt;Students &amp;amp; Learners – for practicing RESTful API testing online.&lt;/li&gt;
&lt;li&gt;If you’re looking for a free Postman alternative or a lightweight API testing tool, API Tester is built for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚀 Try API Tester Now&lt;/p&gt;

&lt;p&gt;👉 Use API Tester Free on &lt;a href="https://www.justinbrowser.com/tools/api-tester" rel="noopener noreferrer"&gt;justinbrowser.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are also other simple, amazing tools in JustInBrowser you can check out. I am actively working on adding more amazing time-saving tools. Let me know if you have some best in mind, I will also work on them.&lt;/p&gt;

&lt;p&gt;POV: If you find any bugs, let me know, and I will fix them.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>api</category>
      <category>testing</category>
    </item>
    <item>
      <title>Why Image Compression Matters for Faster &amp; Smarter Web Apps</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Tue, 09 Sep 2025 09:15:36 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/why-image-compression-matters-for-faster-smarter-web-apps-1ncp</link>
      <guid>https://dev.to/javediqbal8381/why-image-compression-matters-for-faster-smarter-web-apps-1ncp</guid>
      <description>&lt;p&gt;In today’s world, performance is everything. Users don’t wait around for slow-loading apps or websites. If your web app takes more than a few seconds to load, you risk losing visitors and customers.&lt;/p&gt;

&lt;p&gt;One of the biggest culprits of slow apps and websites is uncompressed images.&lt;/p&gt;

&lt;p&gt;📸 Why Image Compression Is Needed&lt;/p&gt;

&lt;p&gt;Images often take up more than 70% of a webpage’s weight. High resolution pictures are beautiful, but they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increase page load time&lt;/li&gt;
&lt;li&gt;Consume more storage space&lt;/li&gt;
&lt;li&gt;Lead to higher bandwidth costs&lt;/li&gt;
&lt;li&gt;Slow down your app on mobile devices with weaker connections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why developers and businesses use image compression — to reduce file size without sacrificing quality.&lt;/p&gt;

&lt;p&gt;How Image Compression Helps Your App&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster load times → Smaller image files mean your users can access content instantly.&lt;/li&gt;
&lt;li&gt;Better SEO ranking → Google and other search engines love fast, lightweight apps.&lt;/li&gt;
&lt;li&gt;Storage efficiency → Save server or device space by reducing image size.&lt;/li&gt;
&lt;li&gt;Improved user experience → Users stay engaged when apps feel smooth and responsive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, image compression = speed, performance, and efficiency.&lt;/p&gt;

&lt;p&gt;🛠️ Try a Free Image Compressor (Client-Side &amp;amp; Privacy-First)&lt;/p&gt;

&lt;p&gt;If you’re looking for a simple, fast, and secure way to compress images, check out the Image Compressor tool by &lt;a href="https://www.justinbrowser.com/tools/image-compressor" rel="noopener noreferrer"&gt;justInBrowser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s why developers love it:&lt;/p&gt;

&lt;p&gt;100% client-side → Your images are processed in your browser, never uploaded to a server.&lt;/p&gt;

&lt;p&gt;Privacy-first → No tracking, no hidden uploads — your files stay on your device.&lt;/p&gt;

&lt;p&gt;Super fast → Built for modern browsers, giving you instant compression.&lt;/p&gt;

&lt;p&gt;Free &amp;amp; easy → No signup, no ads, just drop your images and compress.&lt;/p&gt;

&lt;p&gt;Perfect for web developers, designers, and anyone who wants to make apps faster, save space, and protect user privacy.&lt;/p&gt;

&lt;p&gt;👉 Try it now: &lt;a href="https://www.justinbrowser.com/tools/image-compressor" rel="noopener noreferrer"&gt;https://www.justinbrowser.com/tools/image-compressor&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>SEO for Next.js apps — practical tips that actually work</title>
      <dc:creator>javediqbal8381</dc:creator>
      <pubDate>Sun, 07 Sep 2025 06:54:14 +0000</pubDate>
      <link>https://dev.to/javediqbal8381/seo-for-nextjs-apps-practical-tips-that-actually-work-2cc4</link>
      <guid>https://dev.to/javediqbal8381/seo-for-nextjs-apps-practical-tips-that-actually-work-2cc4</guid>
      <description>&lt;h2&gt;
  
  
  Most
&lt;/h2&gt;

&lt;p&gt;SEO posts rehash the same basics. This one is for developers who already know the basics and want practical Next.js-specific tactics that you can apply today to get better indexing, prettier link previews, and faster real-user experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uqcx4dy3nsd1mq9kg6u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uqcx4dy3nsd1mq9kg6u.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Use the Metadata API (app router) — per page, correctly
&lt;/h2&gt;

&lt;p&gt;If you use the app router, export metadata or generateMetadata from the page/layout. It’s the cleanest way to keep titles, descriptions, canonical links, open graph and favicons consistent per route. When metadata is rendered server side, crawlers and social previews see the right content immediately.&lt;/p&gt;

&lt;p&gt;Example (Static):&lt;/p&gt;

&lt;p&gt;// app/blog/[slug]/page.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const metadata = {
  title: 'How to optimize a blog post',
  description: 'Practical SEO tips for Next.js blog posts',
  alternates: { canonical: 'https://yourdomain.com/blog/my-post' },
  openGraph: {
    title: 'How to optimize a blog post',
    description: 'Practical SEO tips for Next.js',
    images: [{ url: '/og-images/blog-my-post.png', width: 1200, height: 630 }],
  },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example (Dynamic):&lt;br&gt;
// app/blog/[slug]/page.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function generateMetadata({ params }) {
  const post = await getPost(params.slug)
  return {
    title: post.title,
    description: post.excerpt,
    alternates: { canonical: `https://yourdomain.com/blog/${params.slug}` },
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2) Own your sitemap and robots with the app router
&lt;/h2&gt;

&lt;p&gt;Sitemaps still matter. Next.js has first-class helpers for sitemaps in the app router so you can generate sitemaps at build time or split them for very large sites. Keep your sitemap up to date and submit it to Search Console after major updates.&lt;/p&gt;

&lt;p&gt;Tiny example (app router):&lt;/p&gt;

&lt;p&gt;// app/sitemap.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MetadataRoute } from 'next'
import { getAllSlugs } from './lib/cms'

export default async function sitemap(): Promise&amp;lt;MetadataRoute.Sitemap&amp;gt; {
  const slugs = await getAllSlugs()
  return slugs.map(s =&amp;gt; ({
    url: `https://yourdomain.com/blog/${s}`,
    lastModified: new Date().toISOString(),
  }))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then submit &lt;a href="https://yourdomain.com/sitemap.xml" rel="noopener noreferrer"&gt;https://yourdomain.com/sitemap.xml&lt;/a&gt; to Google Search Console, or list it in robots.txt.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Server-render critical content, avoid client-only for SEO text
&lt;/h2&gt;

&lt;p&gt;Google processes JavaScript in stages: crawl, render, index. If your primary content is rendered only on the client, indexing may be delayed or incomplete. Render key content server side (SSG/SSR/ISR) so crawlers immediately see it. Dynamic rendering exists as a fallback but is not recommended long term. &lt;/p&gt;

&lt;p&gt;Quick guideline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Marketing pages and blog posts: SSG or ISR.&lt;/li&gt;
&lt;li&gt;Frequently changing lists (search results): SSR or carefully    designed hybrid.&lt;/li&gt;
&lt;li&gt;Personalised dashboard UI: client-side is fine (not for SEO).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4) Make images SEO-friendly using next/image
&lt;/h2&gt;

&lt;p&gt;Images affect page speed and visual stability. Use next/image for automatic resizing, modern formats and to avoid layout shift. Always include good alt text and a sensible sizes / priority policy for hero images. &lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Image from 'next/image'

export default function Hero({ post }) {
  return (
    &amp;lt;Image
      src={post.hero}
      alt={post.title}
      width={1200}
      height={630}
      priority
      sizes="(max-width: 768px) 100vw, 1200px"
    /&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Use JSON-LD structured data server side for rich results&lt;/p&gt;

&lt;p&gt;JSON-LD still makes it easier for Google to understand your content and can unlock rich snippets like article cards, FAQs, product info and more. Inject JSON-LD from the server so crawlers see it immediately, then validate with Google’s Rich Results Test. Google recommends JSON-LD. &lt;/p&gt;

&lt;p&gt;Example (server component):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const jsonLd = {
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": post.title,
  "datePublished": post.publishedAt,
  "author": { "@type": "Person", "name": post.author },
  "image": post.heroFullUrl,
  "publisher": {
    "@type": "Organization",
    "name": "Your Site",
    "logo": { "@type": "ImageObject", "url": "https://yourdomain.com/logo.png" }
  }
}

export default function HeadTags() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      /&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Out-of-the-box ideas worth trying
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Serve simplified content to crawlers with server components — render a minimal SEO-first layer server-side and hydrate interactive bits later.&lt;/li&gt;
&lt;li&gt;Split large sitemaps dynamically — for very large sites, break sitemaps by date or category so Search Console processes them faster. Next.js supports splitting sitemaps. &lt;/li&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;li&gt;Generate OG images at build time or on demand using Next.js image APIs so every post has a unique share image without manual work. (Metadata API can help here.) &lt;/li&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;li&gt;Use revalidate tags to invalidate groups of pages instead of single paths when your CMS updates a taxonomy. This keeps content consistent without triggering thousands of rebuilds.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
