<?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: ARIJIT PARIA</title>
    <description>The latest articles on DEV Community by ARIJIT PARIA (@arijitparia2002).</description>
    <link>https://dev.to/arijitparia2002</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%2F955163%2Fbbe63f21-6a55-4979-906a-6fb1c327844f.jpeg</url>
      <title>DEV Community: ARIJIT PARIA</title>
      <link>https://dev.to/arijitparia2002</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arijitparia2002"/>
    <language>en</language>
    <item>
      <title>How I Built a Chrome Extension That Eliminates Salesforce Debugging Hell</title>
      <dc:creator>ARIJIT PARIA</dc:creator>
      <pubDate>Mon, 25 Aug 2025 05:09:08 +0000</pubDate>
      <link>https://dev.to/arijitparia2002/how-i-built-a-chrome-extension-that-eliminates-salesforce-debugging-hell-404f</link>
      <guid>https://dev.to/arijitparia2002/how-i-built-a-chrome-extension-that-eliminates-salesforce-debugging-hell-404f</guid>
      <description>&lt;h2&gt;
  
  
  The Problem That Drove Me Crazy
&lt;/h2&gt;

&lt;p&gt;Picture this: It's 4 PM, production is down, and you're debugging a Salesforce issue. You have 17 browser tabs open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tab 1: The user's record causing the error&lt;/li&gt;
&lt;li&gt;Tab 2: Setup → Debug Logs (still loading...)&lt;/li&gt;
&lt;li&gt;Tab 3: Developer Console for SOQL queries&lt;/li&gt;
&lt;li&gt;Tab 4: Setup → Apex Classes to find the trigger&lt;/li&gt;
&lt;li&gt;Tab 5: Back to Debug Logs (404 error now)&lt;/li&gt;
&lt;li&gt;Tabs 6-17: Various Setup pages you opened while hunting for clues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sound familiar? This was my daily reality as a Salesforce developer until I decided to build a solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Challenge
&lt;/h2&gt;

&lt;p&gt;Salesforce's debugging workflow forces developers into a multi-tab nightmare because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Debug logging affects ALL users&lt;/strong&gt; when enabled at the org level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SOQL queries have strict limits&lt;/strong&gt; (50,000 records, offset limitations)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component discovery requires manual navigation&lt;/strong&gt; through Setup menus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No unified debugging interface&lt;/strong&gt; exists within Salesforce&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I needed to solve these problems while working within Salesforce's security constraints and API limitations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: A Modern Chrome Extension
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Salesforce Debugger&lt;/strong&gt; - a comprehensive debugging toolkit that consolidates four essential tools into one interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Stack
&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;// Core architecture&lt;/span&gt;
&lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;TypeScript&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;TailwindCSS&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="nx"&gt;Vite&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="nx"&gt;system&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;CRXJS&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt;
&lt;span class="nx"&gt;Manifest&lt;/span&gt; &lt;span class="nx"&gt;V3&lt;/span&gt; &lt;span class="nx"&gt;extension&lt;/span&gt; &lt;span class="nx"&gt;architecture&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extension uses modern web standards with hot reloading support for development, making it both powerful and maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. APEX Debugger - Safe Multi-User Debugging
&lt;/h3&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%2F8c3dt6asz60yezs0dgwo.png" 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%2F8c3dt6asz60yezs0dgwo.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The biggest breakthrough was solving &lt;strong&gt;user-specific debug logging&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Enable debug logging for specific user only&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;enableDebugTrace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;await&lt;/span&gt; &lt;span class="nx"&gt;salesforceAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/services/data/v58.0/tooling/sobjects/TraceFlag/&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="na"&gt;TracedEntityId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;LogType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DEVELOPER_LOG&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;StartDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;ExpirationDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3600000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;DebugLevelId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getOrCreateDebugLevel&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;Key innovations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User-specific trace flags&lt;/strong&gt; prevent debugging interference in shared orgs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic cleanup&lt;/strong&gt; removes debug artifacts after specified duration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time sync&lt;/strong&gt; updates status across all browser tabs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart log fetching&lt;/strong&gt; with performance metrics and full-text search&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. SOQL Studio - Breaking Query Limitations
&lt;/h3&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%2F76hedukwxmzry88b9qxh.png" 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%2F76hedukwxmzry88b9qxh.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Traditional SOQL queries hit limits quickly. I implemented &lt;strong&gt;cursor-based pagination&lt;/strong&gt; to bypass these constraints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Cursor-based pagination for unlimited results&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;executeUnlimitedQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;soql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;let&lt;/span&gt; &lt;span class="nx"&gt;allRecords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nextRecordsUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;do&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;response&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;salesforceAPI&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="nx"&gt;nextRecordsUrl&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`/services/data/v58.0/query/?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;soql&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;allRecords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;allRecords&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="nx"&gt;records&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;nextRecordsUrl&lt;/span&gt; &lt;span class="o"&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;nextRecordsUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextRecordsUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;allRecords&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;Features include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;50-line query editor&lt;/strong&gt; with syntax highlighting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-completion&lt;/strong&gt; with relationship field traversal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Query management&lt;/strong&gt; - save and organize frequently used queries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time results&lt;/strong&gt; with sorting and navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Smart Search - Metadata Discovery at Scale
&lt;/h3&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%2F00tc30p0f4rtehz7o9f5.png" 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%2F00tc30p0f4rtehz7o9f5.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finding components in large Salesforce orgs is painfully slow. I built a comprehensive search engine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Search across 12 component types simultaneously&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SEARCHABLE_COMPONENTS&lt;/span&gt; &lt;span class="o"&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;ApexClass&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;ApexTrigger&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;LightningComponentBundle&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;AuraDefinitionBundle&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;Flow&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;CustomObject&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;ValidationRule&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;WorkflowRule&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;CustomLabel&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;PermissionSet&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;Layout&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;Report&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;searchMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;searchPromises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SEARCHABLE_COMPONENTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nx"&gt;salesforceAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooling&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="s2"&gt;`SELECT Id, Name, DeveloperName FROM &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 
       WHERE Name LIKE '%&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%' OR DeveloperName LIKE '%&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchPromises&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;This provides &lt;strong&gt;90%+ faster component discovery&lt;/strong&gt; compared to manual Setup navigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. LWC Debugger - Real-Time Component Inspection
&lt;/h3&gt;

&lt;p&gt;For Lightning Web Components, I integrated with Chrome DevTools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Monitor Apex calls from LWC components&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trackApexCalls&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PerformanceObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;list&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;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEntries&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&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;entry&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="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apex&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="nf"&gt;logApexCall&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;extractMethodName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&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="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startTime&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="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;entryTypes&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;measure&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;h2&gt;
  
  
  Real-World Impact
&lt;/h2&gt;

&lt;p&gt;Since launching, the extension has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1,000+ active users&lt;/strong&gt; across development teams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;90%+ reduction&lt;/strong&gt; in component discovery time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero tab switching&lt;/strong&gt; for common debugging tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe multi-user debugging&lt;/strong&gt; in production environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Challenges Overcome
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Salesforce API Limitations
&lt;/h3&gt;

&lt;p&gt;Working within strict API limits while providing unlimited functionality required creative solutions like cursor-based pagination and intelligent batching.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Security Constraints
&lt;/h3&gt;

&lt;p&gt;The extension operates entirely within Salesforce's security model - no bypassing of permissions, all API calls use existing user sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Performance Optimization
&lt;/h3&gt;

&lt;p&gt;Handling large datasets and real-time updates required careful state management and efficient React rendering strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Cross-Tab Synchronization
&lt;/h3&gt;

&lt;p&gt;Maintaining consistent state across multiple Salesforce tabs required implementing a robust messaging system between content scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Extension structure&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;     &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Salesforce&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="nx"&gt;integration&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;popup&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;             &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="nx"&gt;debugging&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;devtools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;          &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;LWC&lt;/span&gt; &lt;span class="nx"&gt;debugging&lt;/span&gt; &lt;span class="nx"&gt;panel&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="nx"&gt;calls&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Reusable&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;            &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Salesforce&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="nx"&gt;helpers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The modular architecture allows for easy feature additions and maintenance while keeping the codebase organized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Learnings
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User-centric design beats feature-rich complexity&lt;/strong&gt; - Solving real workflow problems matters more than adding features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API limitations spark innovation&lt;/strong&gt; - Working within constraints led to better solutions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer tools need developer UX&lt;/strong&gt; - Even internal tools deserve polished interfaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security-first approach builds trust&lt;/strong&gt; - Never compromising on Salesforce security model was crucial&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Currently working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flow debugger&lt;/strong&gt; for visual workflow debugging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance profiler&lt;/strong&gt; for org-wide performance analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team collaboration&lt;/strong&gt; features for shared debugging sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The extension is free and available on the &lt;a href="https://chromewebstore.google.com/detail/salesforce-debugger-all-i/dmfledeppinlciakcinbegohoadmbigm" rel="noopener noreferrer"&gt;Chrome Web Store&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick start:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the extension&lt;/li&gt;
&lt;li&gt;Navigate to any Salesforce org&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Alt+S&lt;/code&gt; for SOQL Studio or click the extension icon&lt;/li&gt;
&lt;li&gt;Start debugging without the tab chaos!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;What's your biggest Salesforce debugging pain point? Have you built solutions to overcome platform limitations? Share your experiences in the comments!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Connect with me:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/arijitparia/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/arijitparia/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Extension link:&lt;/strong&gt; &lt;a href="https://chromewebstore.google.com/detail/salesforce-debugger-all-i/dmfledeppinlciakcinbegohoadmbigm?authuser=0&amp;amp;hl=en" rel="noopener noreferrer"&gt;https://chromewebstore.google.com/detail/salesforce-debugger-all-i/dmfledeppinlciakcinbegohoadmbigm?authuser=0&amp;amp;hl=en&lt;/a&gt;&lt;/p&gt;




</description>
      <category>salesforce</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>chromeextension</category>
    </item>
    <item>
      <title>Mastering Message Passing in Chrome Extensions: From Basics to Advanced Techniques</title>
      <dc:creator>ARIJIT PARIA</dc:creator>
      <pubDate>Fri, 27 Oct 2023 22:05:45 +0000</pubDate>
      <link>https://dev.to/arijitparia2002/mastering-message-passing-in-chrome-extensions-from-basics-to-advanced-techniques-4ana</link>
      <guid>https://dev.to/arijitparia2002/mastering-message-passing-in-chrome-extensions-from-basics-to-advanced-techniques-4ana</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Dive deep into the bustling digital metropolis of Chrome, where each tab stands as a towering skyscraper, teeming with activity and intricate conversations. Here, Chrome extensions play the role of superheroes, adeptly navigating this complex landscape, transmitting messages, and performing awe-inspiring feats. This comprehensive guide is crafted to unveil the secrets of these digital superheroes, focusing on their sophisticated means of communication in the era of Manifest V3, known as "Message Passing."&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 1: Deciphering the Digital Dialogue - The Basics of Message Passing in Manifest V3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 Unraveling Message Passing
&lt;/h3&gt;

&lt;p&gt;Message passing in Chrome extensions, especially with Manifest V3, resembles the art of passing secret notes, executed with unparalleled precision and efficiency. Each message is meticulously addressed, ensuring it navigates through the digital expanse to reach the intended recipient.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code Example: Initiating a Conversation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In a content script, initiating a conversation with the background script&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="na"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello Background, I've stumbled upon something fascinating!&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;h3&gt;
  
  
  1.2 Engaging in a Two-Way Conversation
&lt;/h3&gt;

&lt;p&gt;Sending messages is merely the tip of the iceberg; the true magic unfolds when we engage in interactive, two-way conversations. Chrome extensions in Manifest V3 are designed to excel in this realm, facilitating a seamless dialogue.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code Example: Exchanging Messages and Awaiting Responses
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In a content script, sending a message and awaiting a response&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="na"&gt;inquiry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What should be our next course of action?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kd"&gt;function&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="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="s2"&gt;Received guidance:&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;advice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// In the background script, listening for messages and crafting responses&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="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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="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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inquiry&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What should be our next course of action?&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="nf"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;advice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Analyze the situation and proceed with caution.&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;h2&gt;
  
  
  Section 2: The Digital Post and Telecommunication - Chrome APIs for Message Passing in Manifest V3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Mastering chrome.runtime.sendMessage and chrome.runtime.onMessage
&lt;/h3&gt;

&lt;p&gt;These functions serve as the digital post office of Chrome City, facilitating precise and secure communication across the vast digital landscape.&lt;/p&gt;

&lt;h4&gt;
  
  
  Real-Life Analogy and Code Example
&lt;/h4&gt;

&lt;p&gt;Imagine you've discovered a hidden treasure in one of the skyscrapers. To share this news with a superhero friend in another building, you draft a message and send it via the digital post office.&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;// Sending a message to another part of the extension&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="na"&gt;treasureLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Skyscraper 42, Floor 7&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;h3&gt;
  
  
  2.2 Direct Deliveries with chrome.tabs.sendMessage
&lt;/h3&gt;

&lt;p&gt;When the need arises to communicate directly with a specific room in a particular skyscraper, chrome.tabs.sendMessage is the superhero's tool of choice.&lt;/p&gt;

&lt;h4&gt;
  
  
  Real-Life Analogy and Code Example
&lt;/h4&gt;

&lt;p&gt;Consider this akin to delivering a special package directly to a friend’s apartment, bypassing the building's main entrance for efficiency and precision.&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;// Sending a message directly to a content script in a specific tab&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="kd"&gt;function&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;activeTab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;activeTab&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;greeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, Room 101!&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;h2&gt;
  
  
  Section 3: Mastering the Art of Messaging - Intermediate Techniques in Manifest V3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Balancing Speed and Precision - Synchronous vs. Asynchronous Messaging
&lt;/h3&gt;

&lt;p&gt;In the digital city, superheroes must balance the need for rapid communication with the necessity for precision. Synchronous messaging offers instant responses, while asynchronous messaging allows for a more measured pace.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example and Explanation: Synchronous vs. Asynchronous Messaging
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous&lt;/strong&gt;: A superhero sends a message and pauses, awaiting an immediate response. This is akin to a phone call, where the conversation unfolds in real-time.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// Example of synchronous messaging (pseudo-code, as true synchronous messaging isn't supported in Manifest V3)&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;synchronousMessage&lt;/span&gt;&lt;span class="p"&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;response&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;sendMessageSync&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="s2"&gt;getInfo&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;Immediate 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="nf"&gt;synchronousMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous&lt;/strong&gt;: A superhero sends a message and continues with other tasks, receiving a response at a later time. This resembles email communication, where responses are not instantaneous.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// Example of asynchronous messaging&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;asynchronousMessage&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;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="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="s2"&gt;getInfo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kd"&gt;function&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="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="s2"&gt;Response received later:&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="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="s2"&gt;Message sent, continuing with other tasks&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="nf"&gt;asynchronousMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Broadcasting to the Masses - One-to-Many Communication
&lt;/h3&gt;

&lt;p&gt;There are moments when a superhero needs to broadcast a message to all allies simultaneously, ensuring that everyone receives the information at the same time.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example and Explanation: One-to-Many Communication
&lt;/h4&gt;

&lt;p&gt;Imagine a scenario where a superhero needs to make an urgent announcement to all other superheroes in the city. This requires a one-to-many communication approach.&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;// Broadcasting a message to all content scripts in all open tabs&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="kd"&gt;function&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="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;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="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;announcement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Urgent: All superheroes, assemble!&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;h2&gt;
  
  
  Section 4: Navigating Advanced Terrain - Advanced Concepts and Manifest V3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Bridging Digital Cities - Cross-Origin Communication
&lt;/h3&gt;

&lt;p&gt;Sometimes, our superhero needs to communicate with allies in a different digital city (or website). This requires special permissions and a careful setup, but it is achievable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example and Explanation: Cross-Origin Communication
&lt;/h4&gt;

&lt;p&gt;A superhero in Chrome City needs to send a crucial message to a superhero in Firefox City. With the right permissions and setup, cross-browser communication becomes possible.&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;// Example of cross-origin communication (pseudo-code, as this requires additional setup and permissions)&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;extensionIdInFirefoxCity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from Chrome City!&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;h3&gt;
  
  
  4.2 Harnessing the Power of Manifest V3 - Advanced Message Passing
&lt;/h3&gt;

&lt;p&gt;With the advent of Manifest V3, Chrome extensions have undergone a significant transformation, leading to faster and more secure operations. The message passing mechanism has been refined, ensuring smoother and more secure interactions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Explanation: The Advancements in Message Passing with Manifest V3
&lt;/h4&gt;

&lt;p&gt;Manifest V3 introduces service workers, replacing background pages. This change enhances the performance and security of message passing, as service workers are event-driven and do not persist between messages. This ensures a more efficient use of resources and a more secure messaging environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 5: Envisioning
&lt;/h2&gt;

&lt;p&gt;the Future - Future Possibilities with Manifest V3&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1 Pondering the Possibilities
&lt;/h3&gt;

&lt;p&gt;As we look ahead, the future is filled with endless possibilities for our digital superheroes. They might find innovative ways to communicate with entities from other digital realms or master new forms of digital language, further expanding their capabilities.&lt;/p&gt;

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

&lt;p&gt;You have now ascended to the ranks of a Super Messenger in the digital city of Chrome, mastering the intricate art of message passing, navigating various speeds of communication, making impactful announcements, and embracing the latest in superhero technology. Continue to refine your skills, and you will play a pivotal role in elevating Chrome City to new heights of excellence and innovation!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Deploy a simple web app using Firebase</title>
      <dc:creator>ARIJIT PARIA</dc:creator>
      <pubDate>Thu, 16 Mar 2023 20:41:24 +0000</pubDate>
      <link>https://dev.to/arijitparia2002/deploy-a-simple-web-app-using-firebase-5344</link>
      <guid>https://dev.to/arijitparia2002/deploy-a-simple-web-app-using-firebase-5344</guid>
      <description>&lt;p&gt;For many people, creating a website has become a popular pastime. Having an internet presence has become crucial, whether for personal or corporate reasons. It's now simpler than ever to design a website that looks and works precisely way you want it to with the aid of HTML, CSS, and JavaScript.&lt;/p&gt;

&lt;p&gt;Hosting a website to allow for global accessibility is one of the most crucial steps in website creation. An fantastic alternative for hosting a website is Firebase, which also provides a free plan for launching smaller projects. We'll examine how to develop a straightforward website using HTML, CSS, and JavaScript in this blog article before deploying it with Firebase.&lt;/p&gt;

&lt;p&gt;Let's build the website first. To improve its appearance and functionality, we'll start with a simple HTML file and add some CSS and JavaScript. The HTML source code is provided here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;My Website&amp;lt;/title&amp;gt;
    &amp;lt;link rel="stylesheet" href="styles.css"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to My Website&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;This is my first website!&amp;lt;/p&amp;gt;
    &amp;lt;button onclick="changeColor()"&amp;gt;Change Color&amp;lt;/button&amp;gt;
    &amp;lt;script src="app.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;We've added a body, a button with text, and a header. To style our HTML components, we also included a CSS file. Lastly, we included a JavaScript file that, when activated by the button, will alter the page's background color. The code for our CSS file is shown here&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;body {
  background-color: white;
  color: black;
  font-family: Arial, sans-serif;
  font-size: 24px;
}

button {
  background-color: blue;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

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

&lt;/div&gt;



&lt;p&gt;The body's background color, font family, and font size are all determined by our CSS file. For our button, we also included certain styles, such as the background color, padding, border, and border radius.&lt;/p&gt;

&lt;p&gt;Let's now update our &lt;strong&gt;app.js&lt;/strong&gt; file with the JavaScript code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function changeColor() {
  document.body.style.backgroundColor = "pink";
}

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

&lt;/div&gt;



&lt;p&gt;When the button is pressed, a method in our JavaScript code causes the page's backdrop to turn pink.&lt;/p&gt;

&lt;p&gt;It's time to launch our website utilizing Firebase now that everything has been finished. We must first register for a free Firebase account. After registering, we may activate the Firebase Command Line Interface (CLI) on our computer by installing it.&lt;/p&gt;

&lt;p&gt;We must establish a Firebase project and initialize it with the Firebase CLI before we can launch our website. The following commands need to be entered into the terminal to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firebase login
firebase init

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

&lt;/div&gt;



&lt;p&gt;After installing the Firebase CLI, launch the command &lt;strong&gt;firebase init&lt;/strong&gt; in the terminal by navigating to the root directory of your website project. With the help of this command, you may set up your Firebase project by responding to a series of questions.&lt;/p&gt;

&lt;p&gt;You will be requested to choose the Firebase services you wish to utilize during the startup process. You could decide to employ Authentication, Realtime Database, or Firebase Hosting, for instance.&lt;/p&gt;

&lt;p&gt;You will be prompted to configure your Firebase project after choosing the Firebase services you wish to utilize. You have the option of making a new Firebase project or using an existing one. You will be asked to input a special project ID and project name if you decide to establish a new project.&lt;/p&gt;

&lt;p&gt;The Firebase CLI will produce a &lt;strong&gt;.firebaserc&lt;/strong&gt; file in your project directory after the configuration procedure is complete. Your Firebase project ID and the aliases for the Firebase services you choose are contained in this file.&lt;/p&gt;

&lt;p&gt;You'll next be asked to configure Firebase Hosting for your website. Using an existing Firebase Hosting site or building a new one is your choice. You will be asked to submit a special site name if you decide to create a new site.&lt;/p&gt;

&lt;p&gt;In order to choose the public directory for your website, you will finally be requested. You may find your HTML, CSS, and JavaScript files under this directory. By default, Firebase Hosting will search this directory for an &lt;code&gt;index.html&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Use the command &lt;code&gt;firebase deploy&lt;/code&gt; to begin deploying your website to Firebase Hosting after the initialization procedure is complete. By using this command, you may publish your website and upload its files to the Firebase server.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow me on &lt;a href="https://www.linkedin.com/in/arijit-paria-0234261b7/" rel="noopener noreferrer"&gt; linkedIn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Check out my &lt;a href="https://www.youtube.com/@TUTORIEX_" rel="noopener noreferrer"&gt;Youtube &lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>firebase</category>
      <category>webapp</category>
    </item>
  </channel>
</rss>
