<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ devtools - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ devtools - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 17 May 2026 11:35:52 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/devtools/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Table of Contents for Your Article ]]>
                </title>
                <description>
                    <![CDATA[ When you create an article, such as a blog post for freeCodeCamp, Hashnode, Medium, or DEV.to, you can help guide the reader by creating a Table of Contents (ToC). In this article, I'll explain how to ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-table-of-contents-for-your-article/</link>
                <guid isPermaLink="false">69b27bc5f22e712aaa45f840</guid>
                
                    <category>
                        <![CDATA[ blog ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ devtools ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jakub T. Jankiewicz ]]>
                </dc:creator>
                <pubDate>Thu, 12 Mar 2026 08:39:33 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/ff72c490-a57b-46c4-b0d9-8c2654853b7c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When you create an article, such as a blog post for freeCodeCamp, Hashnode, Medium, or DEV.to, you can help guide the reader by creating a <a href="https://en.wikipedia.org/wiki/Table_of_contents">Table of Contents</a> (ToC). In this article, I'll explain how to create one with the help of JavaScript and browser DevTools. The article will explain how to use Google Chrome Dev Tools. But the same can be applied to any modern browser.</p>
<p>The process in this article needs to be done once per platform. Once you have the code, you can apply it every time to create a ToC. Note that if the platform changes something, you may need to adjust the script.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-browser-dev-tools">Browser Dev Tools</a></p>
</li>
<li><p><a href="#heading-javascript-console">JavaScript Console</a></p>
</li>
<li><p><a href="#heading-understanding-the-dom-structure">Understanding the DOM Structure</a></p>
</li>
<li><p><a href="#heading-creating-toc-in-markdown">Creating TOC in Markdown</a></p>
</li>
<li><p><a href="#heading-how-to-create-an-html-toc">How to create an HTML TOC?</a></p>
</li>
<li><p><a href="#heading-copy-the-html-code-for-the-editor">Copy the HTML code for the editor</a></p>
</li>
<li><p><a href="#heading-what-to-do-if-i-dont-have-headers">What to do if I don’t have headers?</a></p>
<ul>
<li><a href="#heading-create-table-of-contents-for-devto">Create Table of Contents for</a> <a href="http://DEV.to">DEV.to</a></li>
</ul>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-browser-dev-tools">Browser Dev Tools</h2>
<p>Dev Tools is an extension to the browser that can allow you to inspect and manipulate the DOM (<a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model">Document Object Model</a>), which is a representation of the HTML the browser keeps in memory in the form of a tree. It also gives access to the JavaScript console, where you can write short code snippets to test something. It has a lot more features, but we'll only use those two.</p>
<p>To open Dev Tools (in Google Chrome), you can press F12 or right-click on the page with your mouse and click Inspect.</p>
<div>
<div>⚠</div>
<div>In Safari, the browser Dev Tools are disabled initially. To enable it, read: <a target="_self" rel="noopener" class="text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer eVNpHGjtxRBq_gLOfGDr LQNqh2U1kzYxREs65IJu" href="https://support.apple.com/guide/safari/use-the-developer-tools-in-the-develop-menu-sfri20948/mac" style="pointer-events:none">Use the developer tools in the Develop menu in Safari on Mac</a>.</div>
</div>

<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763748137160/7e4df24f-6d25-4d43-a67b-c671bd85789a.png" alt="A browser window split in half. One the right there is an illustration of the laptop with FreeCodeCamp article on the right there is browser DevTools with DOM Tree and CSS panel." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Above is the screenshot of DevTools with a preview of this article. On the right, you can see a selected <code>h1</code> HTML tag (the title) and CSS applied to that tag. The tree structure you see is the DOM.</p>
<div>
<div>💡</div>
<div>When creating a ToC for <strong>freeCodeCamp,</strong> you should open the preview in a new tab.</div>
</div>

<h2 id="heading-javascript-console">JavaScript Console</h2>
<p>We will need to have access to the JavaScript console. To open the console in Google Chrome, you can use F12, right-click on the page and select Inspect from the context menu, or use the shortcut CTRL+SHIFT+C (Windows, Linux) or CMD+OPTION+C (Mac).</p>
<p>In Chrome DevTools, you can pick the Console tab at the top of the DevTools. But this will hide the DOM tree. It’s better to open the bottom drawer. You need to click the 3 dots in the top right corner and pick “show console drawer”.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763749509540/7968ace9-624e-4037-b09a-fe298ba9b865.png" alt="Screenshot of a menu whic hallow docking the dev tools to the right, left, bottom, or in standalone window." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>The Dev Tools will look like this:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763749614077/640a2467-ac85-4788-9836-3431a1c503bb.png" alt="Screenshot of Browser DevTools showing DOM Tree, CSS panel, and Console Drawer." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<div>
<div>💡</div>
<div>You can ignore any errors or warnings in the console. You can click this icon 🚫 on the left side of the drawer, and it will clear the console.</div>
</div>

<p>The console is a so-called <a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">Read-Eval-Print-Loop</a>. A classic interface, where you type some commands, here JavaScript code, and when you press enter, the code is executed in the context of the page the DevTools is on.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763749997534/b61f8cc0-62eb-4586-9898-d41a7519cf3e.png" alt="Screenshot which shows browser alert popup and JavaScript code in DevTools console which open the alert." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Above, you can see a page alert executed from the console.</p>
<h2 id="heading-understanding-the-dom-structure">Understanding the DOM Structure</h2>
<p>The first step to create a ToC is to inspect the DOM and find the headers. They are usually <strong>H1…H6</strong> tags. H1 is often the title of the page. In an ideal world, it would always be.</p>
<p>In my case, the header looks like this:</p>
<pre><code class="language-xml">&lt;h2 id="heading-dev-tools"&gt;Dev Tools&lt;/h2&gt;
</code></pre>
<p>The article only has H2 tags, but later in the article, I will also explain how to create a nested ToC.</p>
<div>
<div>💡</div>
<div>Your headers need to have an “id” attribute. It can look different, for example, be on a different element, but it has to be in the DOM. Later in the article, I will explain a few different structures and how to handle them.</div>
</div>

<p>Now with DevTools, we can write code that will find every header:</p>
<pre><code class="language-javascript">document.querySelectorAll('h2[id], h3[id], main h4[id]');
</code></pre>
<p>In the case of my article on freeCodeCamp, it returned this output:</p>
<pre><code class="language-plaintext">NodeList(5)&nbsp;[h2#heading-dev-tools, h2#heading-javascript-console, h2#heading-understanding-the-dom-structure, h2#trending-guides.col-header, h2#mobile-app.col-header]
</code></pre>
<p>First, it’s a NodeList that we need to convert to an Array. Second is that besides our headers that we have so far, we also have two headers that are part of the website and not the main content. So we need to find out the single element that is the parent of the headers we need.</p>
<p>You can right-click on the white page that contains the article and pick <strong>Inspect Element</strong>. In our case, it found an element <code>&lt;main&gt;</code>. So we can rewrite our selector as:</p>
<pre><code class="language-javascript">document.querySelectorAll('main h2[id], main h3[id], main h4[id]');
</code></pre>
<p>And now it returns our headers and nothing more.</p>
<div>
<div>💡</div>
<div>The <code>[id]</code> attribute selector is not needed here, actually. At least not on freeCodeCamp.</div>
</div>

<h2 id="heading-how-to-create-the-toc-in-markdown">How to Create the ToC in Markdown</h2>
<p>A lot of blogging platforms support Markdown, so it'll be the first thing we'll create.</p>
<p>First, we'll convert the Node list to an array. We can use the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread operator</a>:</p>
<pre><code class="language-javascript">[...document.querySelectorAll('main h2[id], main h3[id], main h4[id]')];
</code></pre>
<p>Then we can map over the array and create the Markdown links that point to the given header.</p>
<pre><code class="language-javascript">const headers = [...document.querySelectorAll('main h2[id], main h3[id], main h4[id]')];

headers.map(function(node) {
    // H2 header should have 0 indent
    const level = parseInt(node.nodeName.replace('H', '')) - 2;
    const hash = node.getAttribute('id');
    const indent = ' '.repeat(level * 2);
    return `\({indent}* [\){node.innerText}](#${hash})`;
});
</code></pre>
<p>The output looks like this:</p>
<pre><code class="language-plaintext">(4)&nbsp;['* [Dev Tools](#heading-dev-tools)', '* [JavaScript Console](#heading-javascript-console)', '* [Understanding the DOM Structure](#heading-understanding-the-dom-structure)', '* [What to do if I don’t have headers?](#heading-what-to-do-if-i-dont-have-headers)']
</code></pre>
<p>To get the text, we can join the array with a newline character and use <code>console.lo</code>g to display the output. If we don’t use <code>console.log</code>, it will show a string with <code>\n</code> characters.</p>
<pre><code class="language-javascript">const headers = [...document.querySelectorAll('main h2[id], main h3[id], main h4[id]')];

console.log(headers.map(function(node) {
    // H2 header should have 0 indent
    const level = parseInt(node.nodeName.replace('H', '')) - 2;
    const hash = node.getAttribute('id');
    const indent = ' '.repeat(level * 2);
    return `\({indent}* [\){node.innerText}](#${hash})`;
}).join('\n'));
</code></pre>
<p>The output for this article will look like this:</p>
<pre><code class="language-markdown">* [Dev Tools](#heading-dev-tools)
* [JavaScript Console](#heading-javascript-console)
* [Understanding the DOM Structure](#heading-understanding-the-dom-structure)
* [Creating TOC in Markdown](#heading-creating-toc-in-markdown)
  * [This is fake header](#heading-this-is-fake-header)
</code></pre>
<p>I created one fake subheader. Platforms, even when not supporting Markdown when writing articles, often support Markdown when copy-pasted. The ToC at the top of the article was created by copying and pasting markdown generated with the last JavaScript snippet.</p>
<h2 id="heading-how-to-create-an-html-toc">How to Create an HTML ToC</h2>
<p>If your platform doesn’t support Markdown (like Medium), you can create HTML, preview that HTML, and copy the output to the clipboard. Pasting that into the editor of the platform you're using should keep the formatting.</p>
<div>
<div>💡</div>
<div>On Medium, the content is inside a <code>&lt;section&gt;</code> element, so the selector must be updated.</div>
</div>

<p>To convert Markdown to HTML, you can use any online tool, but you'll see how to create it yourself in the snippet. It will be faster after you create the code.</p>
<pre><code class="language-javascript">const headers = [...document.querySelectorAll('main h2[id], main h3[id], main h4[id]')]

function indent(state) {
    return ' '.repeat((state.level - 1) * 2);
}

function closeUlTags(state, targetLevel) {
    while (state.level &gt; targetLevel) {
        state.level--;
        state.lines.push(`${indent(state)}&lt;/ul&gt;`);
    }
}

function openUlTags(state, targetLevel) {
    while (state.level &lt; targetLevel) {
        state.lines.push(`${indent(state)}&lt;ul&gt;`);
        state.level++;
    }
}

const result = headers.reduce((state, node) =&gt; {
    const level = parseInt(node.nodeName.replace('H', ''));

    closeUlTags(state, level);
    openUlTags(state, level);
    
    const hash = node.getAttribute('id');
    state.lines.push(`\({indent(state)}&lt;li&gt;&lt;a href="#\){hash}"&gt;${node.innerText}&lt;/a&gt;&lt;/li&gt;`);
    return state;
}, { lines: [], level: 1 });

closeUlTags(result, 1);

console.log(result.lines.join('\n'));
</code></pre>
<p>This is the output of the code in this article:</p>
<pre><code class="language-html">&lt;ul&gt;
  &lt;li&gt;&lt;a href="#heading-table-of-contents"&gt;Table of Contents&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#heading-dev-tools"&gt;Dev Tools&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#heading-javascript-console"&gt;JavaScript Console&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#heading-understanding-the-dom-structure"&gt;Understanding the DOM Structure&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#heading-creating-toc-in-markdown"&gt;Creating TOC in Markdown&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#heading-how-to-create-html-toc"&gt;How to create HTML TOC&lt;/a&gt;&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href="#heading-level-3"&gt;Level 3&lt;/a&gt;&lt;/li&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href="#heading-level-4"&gt;Level 4&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;li&gt;&lt;a href="#heading-what-to-do-if-i-dont-have-headers"&gt;What to do if I don’t have headers?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>I added a few headers at the end, so you can see that it will work for any level of nested headers. Note that we also have the ToC as the first element on the list.</p>
<div>
<div>💡</div>
<div>Note that the above HTML code includes a link to the Table of Contents. This happens if you run the script again after adding the TOC. You can remove it by hand. If you want to improve the code, you can add a filter.</div>
</div>

<h2 id="heading-copy-the-html-code-for-the-editor">Copy the HTML code for the editor</h2>
<p>Most so-called <a href="https://en.wikipedia.org/wiki/WYSIWYG">WYSIWYG</a> editors are using HTML, and you should be able to copy the output of HTML code with formatting and paste it into that editor. The easiest is to just save that into a file, open that file, and select the text:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763758802247/7e4fa0cd-377d-44ca-9cdb-b53ec14da4b8.png" alt="Screenshot of the browser window with file open. The page in the browser shows the table of content where all text is highlighted by selection." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-what-to-do-if-i-dont-have-headers">What to Do If I Don’t Have Headers?</h2>
<p>You need to find anything that can be targeted with CSS. If they are <code>p</code> tags with a specific class (like header), you can use <code>p.header</code> instead of <code>h2</code>.</p>
<h3 id="heading-how-to-create-a-table-of-contents-for-devto">How to Create a Table of Contents for DEV.to</h3>
<p>If you have a different DOM structure, you can use different DOM methods to extract the element you need. For example, on DEV.to, the headers look like this:</p>
<pre><code class="language-xml">&lt;h2&gt;
  &lt;a name="overview" href="#overview"&gt;
  &lt;/a&gt;
  Overview
&lt;/h2&gt;
</code></pre>
<p>So the selector needs to be just <code>main h2</code>. But when you execute this code:</p>
<pre><code class="language-javascript">[...document.querySelectorAll('main h2, main h3, main h4')];
</code></pre>
<p>You will see that there are way more headers than the content of the document. Luckily, we can use a new selector in CSS <code>:has()</code>. The final selector for one header can look like this: <code>main h2:has(a[name])</code>.</p>
<p>Here is the full code:</p>
<pre><code class="language-javascript">const selector = 'main h2:has(a[name]), main h3:has(a[name]), main h4:has(a[name])';
const headers = [...document.querySelectorAll(selector)];

console.log(headers.map(function(node) {
    // H2 header should have 0 indent
    const level = parseInt(node.nodeName.replace('H', '')) - 2;
    // this is how you get the hash
    // you can also access href attribute and remove # from the output string
    const hash = node.querySelector('a').getAttribute('name');
    const indent = ' '.repeat(level);
    return `\({indent}* [\){node.innerText}](#${hash})`;
}).join('\n'));
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Creating a table of contents can help your readers digest your article. Since most people don’t read the whole article, they only scan for what they need. You can also find a lot of articles about its impact on SEO. So it’s always worth adding one if the article is longer.</p>
<p>And as you can see, creating a ToC is not that hard with a bit of web development knowledge.</p>
<p>If you like this article, you may want to follow me on Social Media: (<a href="https://x.com/jcubic">Twitter/X</a>, <a href="https://github.com/jcubic">GitHub</a>, and/or <a href="https://www.linkedin.com/in/jakubjankiewicz/">LinkedIn</a>). You can also check my <a href="https://jakub.jankiewicz.org/">personal website</a> and my <a href="https://jakub.jankiewicz.org/blog/">new blog</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Chrome Extension That Analyzes Any Web Page Using JavaScript and Manifest V3 ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever visited a website and wondered how well is this page structured? Does it have a meta description? How many links or headings does it use? Usually, you’d open DevTools or an SEO auditing tool to find answers to these questions. But what ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-chrome-extension-using-javascript-and-manifest-v3/</link>
                <guid isPermaLink="false">6900f612596c2221585d95a4</guid>
                
                    <category>
                        <![CDATA[ chrome extension ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ai seo ]]>
                    </category>
                
                    <category>
                        <![CDATA[ devtools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Hitesh Chauhan ]]>
                </dc:creator>
                <pubDate>Tue, 28 Oct 2025 16:57:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761670419000/13ac96ca-6e28-413f-a0e0-56ed353a007c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever visited a website and wondered how well is this page structured? Does it have a meta description? How many links or headings does it use?</p>
<p>Usually, you’d open DevTools or an SEO auditing tool to find answers to these questions. But what if you could analyze any web page instantly, without leaving your browser?</p>
<p>In this tutorial, you’ll learn how to build a Chrome extension that scans and analyzes any webpage for titles, meta descriptions, headings, and links.</p>
<p>By the end of this article, you’ll:</p>
<ul>
<li><p>Understand how Manifest V3 works in Chrome Extensions</p>
</li>
<li><p>Learn how to inject content scripts into web pages</p>
</li>
<li><p>Build a popup UI that fetches and displays structured data</p>
</li>
<li><p>Explore how this same foundation can be extended with AI-powered insights</p>
</li>
</ul>
<p>💡 This guide focuses on learning and education – no frameworks or build tools required. Just HTML, CSS, and vanilla JavaScript.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-1-understanding-how-chrome-extensions-work">Step 1: Understanding How Chrome Extensions Work</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-set-up-the-project-structure">Step 2: Set Up the Project Structure</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-define-the-manifest-file">Step 3: Define the Manifest File</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-create-the-popup-ui">Step 4: Create the Popup UI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-write-the-content-script-contentjs">Step 5: Write the Content Script (content.js)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-6-connect-the-popup-and-content-script">Step 6: Connect the Popup and Content Script</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-7-load-and-test-your-extension">Step 7: Load and Test Your Extension</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-8-add-optional-enhancements">Step 8: Add Optional Enhancements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-9-publish-to-the-chrome-web-store">Step 9: Publish to the Chrome Web Store</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-thoughts">Final Thoughts</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">🧰 Prerequisites</h2>
<p>Before starting this tutorial, make sure you have:</p>
<ul>
<li><p>A basic understanding of HTML, CSS, and JavaScript</p>
</li>
<li><p>A recent version of Google Chrome installed on your system</p>
</li>
<li><p>Familiarity with using Chrome DevTools (optional but helpful)</p>
</li>
<li><p>A code editor like VS Code or Sublime Text</p>
</li>
<li><p>A local folder where you can create and organize your extension files</p>
</li>
</ul>
<p>💡 Again, no frameworks or build tools are required. We’ll use only vanilla JavaScript and simple web technologies throughout this guide.</p>
<h2 id="heading-step-1-understanding-how-chrome-extensions-work">🧩 Step 1: Understanding How Chrome Extensions Work</h2>
<p>A Chrome extension is just a bundle of web technologies – HTML, CSS, and JS – that extends browser functionality.</p>
<p>Extensions can have multiple parts:</p>
<ul>
<li><p><strong>Manifest file</strong> (<code>manifest.json</code>): defines permissions, icons, and structure.</p>
</li>
<li><p><strong>Content scripts</strong>: run inside web pages and access the DOM.</p>
</li>
<li><p><strong>Background scripts</strong>: handle long-running or event-driven logic.</p>
</li>
<li><p><strong>Popup UI</strong>: what users see when they click your extension icon.</p>
</li>
</ul>
<p>Here’s a high-level flow of what we’ll build:</p>
<pre><code class="lang-plaintext">[Popup UI] &lt;—&gt; [Content Script] &lt;—&gt; [Web Page DOM]
</code></pre>
<p>When the user clicks “Analyze,” the popup will send a message to the content script. The script will then read the DOM and send back results like page title, description, headings, and links.</p>
<h2 id="heading-step-2-set-up-the-project-structure">🧠 Step 2: Set Up the Project Structure</h2>
<p>Create a new folder called <code>page-analyzer-extension</code>. Inside it, create these files:</p>
<pre><code class="lang-plaintext">page-analyzer-extension/
│
├── manifest.json
├── popup.html
├── popup.js
├── content.js
├── styles.css
└── icons/
    ├── icon16.png
    ├── icon48.png
    └── icon128.png
</code></pre>
<p>Icons are optional, but they make the extension look professional. You can use placeholders or generate them from <a target="_blank" href="https://favicon.io/">favicon.io</a>.</p>
<h2 id="heading-step-3-define-the-manifest-file">⚙️ Step 3: Define the Manifest File</h2>
<p>Create <code>manifest.json</code> and paste this in:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"manifest_version"</span>: <span class="hljs-number">3</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Page Analyzer"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Analyze any web page for its title, description, headings, and links."</span>,
  <span class="hljs-attr">"permissions"</span>: [<span class="hljs-string">"activeTab"</span>, <span class="hljs-string">"scripting"</span>],
  <span class="hljs-attr">"action"</span>: {
    <span class="hljs-attr">"default_popup"</span>: <span class="hljs-string">"popup.html"</span>,
    <span class="hljs-attr">"default_icon"</span>: {
      <span class="hljs-attr">"16"</span>: <span class="hljs-string">"icons/icon16.png"</span>,
      <span class="hljs-attr">"48"</span>: <span class="hljs-string">"icons/icon48.png"</span>,
      <span class="hljs-attr">"128"</span>: <span class="hljs-string">"icons/icon128.png"</span>
    }
  },
  <span class="hljs-attr">"content_scripts"</span>: [
    {
      <span class="hljs-attr">"matches"</span>: [<span class="hljs-string">"&lt;all_urls&gt;"</span>],
      <span class="hljs-attr">"js"</span>: [<span class="hljs-string">"content.js"</span>]
    }
  ]
}
</code></pre>
<p>Let’s break this down:</p>
<ul>
<li><p><code>manifest_version: 3</code>: the latest version with security and performance improvements</p>
</li>
<li><p><code>permissions</code>: allow the extension to access the active tab and run scripts</p>
</li>
<li><p><code>content_scripts</code>: define which JS files should automatically run in web pages</p>
</li>
</ul>
<h2 id="heading-step-4-create-the-popup-ui">🧩 Step 4: Create the Popup UI</h2>
<p>The popup appears when users click the extension icon.</p>
<p><code>popup.html</code>:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Page Analyzer<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"styles.css"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Page Analyzer<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Click below to analyze the current page:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"analyze"</span>&gt;</span>Analyze Page<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"results"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"popup.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><code>styles.css</code>:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">font-family</span>: system-ui, sans-serif;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">12px</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">280px</span>;
}
<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#2563eb</span>;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span> <span class="hljs-number">14px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">6px</span>;
  <span class="hljs-attribute">cursor</span>: pointer;
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">500</span>;
}
<span class="hljs-selector-id">#results</span> {
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">12px</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">13px</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.4</span>;
  <span class="hljs-attribute">word-wrap</span>: break-word;
}
</code></pre>
<h2 id="heading-step-5-write-the-content-script-contentjs">🧠 Step 5: Write the Content Script (<code>content.js</code>)</h2>
<p>This script will analyze the web page.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">analyzePage</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> title = <span class="hljs-built_in">document</span>.title || <span class="hljs-string">"No title found"</span>;
  <span class="hljs-keyword">const</span> description =
    <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'meta[name="description"]'</span>)?.content || <span class="hljs-string">"No description found"</span>;
  <span class="hljs-keyword">const</span> headings = <span class="hljs-built_in">Array</span>.from(<span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"h1, h2, h3"</span>)).map(<span class="hljs-function">(<span class="hljs-params">h</span>) =&gt;</span>
    h.innerText.trim()
  );
  <span class="hljs-keyword">const</span> links = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"a"</span>).length;

  <span class="hljs-keyword">return</span> {
    title,
    description,
    headings,
    <span class="hljs-attr">linkCount</span>: links,
    <span class="hljs-attr">domain</span>: location.hostname,
  };
}

chrome.runtime.onMessage.addListener(<span class="hljs-function">(<span class="hljs-params">message, sender, sendResponse</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (message.action === <span class="hljs-string">"analyze"</span>) {
    sendResponse(analyzePage());
  }
});
</code></pre>
<p>What’s happening here:</p>
<ul>
<li><p>We extract the title, description, headings, and total link count</p>
</li>
<li><p>We return this data as a structured object</p>
</li>
<li><p>The script listens for messages from the popup and responds with the analysis</p>
</li>
</ul>
<h2 id="heading-step-6-connect-the-popup-and-content-script">⚡ Step 6: Connect the Popup and Content Script</h2>
<p>In <code>popup.js</code>, add the logic that triggers page analysis.</p>
<pre><code class="lang-js"><span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"analyze"</span>).addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> [tab] = <span class="hljs-keyword">await</span> chrome.tabs.query({ <span class="hljs-attr">active</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">currentWindow</span>: <span class="hljs-literal">true</span> });

  chrome.tabs.sendMessage(tab.id, { <span class="hljs-attr">action</span>: <span class="hljs-string">"analyze"</span> }, <span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> resultContainer = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"results"</span>);

    <span class="hljs-keyword">if</span> (!response) {
      resultContainer.innerText = <span class="hljs-string">"Unable to analyze this page."</span>;
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> { title, description, headings, linkCount, domain } = response;
    resultContainer.innerHTML = <span class="hljs-string">`
      &lt;strong&gt;Domain:&lt;/strong&gt; <span class="hljs-subst">${domain}</span>&lt;br/&gt;
      &lt;strong&gt;Title:&lt;/strong&gt; <span class="hljs-subst">${title}</span>&lt;br/&gt;
      &lt;strong&gt;Description:&lt;/strong&gt; <span class="hljs-subst">${description}</span>&lt;br/&gt;
      &lt;strong&gt;Headings:&lt;/strong&gt; <span class="hljs-subst">${
        headings.length ? headings.join(<span class="hljs-string">", "</span>) : <span class="hljs-string">"No headings found"</span>
      }</span>&lt;br/&gt;
      &lt;strong&gt;Links:&lt;/strong&gt; <span class="hljs-subst">${linkCount}</span>
    `</span>;
  });
});
</code></pre>
<p>This uses the <strong>Chrome Tabs API</strong> to find the current tab and send a message to the content script. When the script responds, we update the popup with the results.</p>
<h2 id="heading-step-7-load-and-test-your-extension">🧪 Step 7: Load and Test Your Extension</h2>
<ol>
<li><p>Open chrome://extensions/</p>
</li>
<li><p>Enable Developer Mode</p>
</li>
<li><p>Click Load Unpacked</p>
</li>
<li><p>Select your project folder</p>
</li>
</ol>
<p>Now, pin your extension to the toolbar, open any website, and click “Analyze Page.”</p>
<p>You’ll instantly see:</p>
<ul>
<li><p>The page’s title</p>
</li>
<li><p>Meta description</p>
</li>
<li><p>Extracted headings (H1–H3)</p>
</li>
<li><p>Link count</p>
</li>
<li><p>Domain name</p>
</li>
</ul>
<p>🎉 Congratulations! You’ve built a working web page analyzer.</p>
<h2 id="heading-step-8-add-optional-enhancements">🧩 Step 8: Add Optional Enhancements</h2>
<p>Now that the basics work, here are some ways to level up your project.</p>
<h3 id="heading-1-add-ai-insights">🧠 1. Add AI Insights</h3>
<p>You can connect to an AI API (like OpenAI or Gemini) to summarize the page or evaluate SEO structure.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Example: pseudo-code for calling an AI API</span>
<span class="hljs-keyword">const</span> aiResponse = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://api.openai.com/v1/chat/completions"</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
  <span class="hljs-attr">headers</span>: { <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">${API_KEY}</span>`</span> },
  <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
    <span class="hljs-attr">model</span>: <span class="hljs-string">"gpt-4o-mini"</span>,
    <span class="hljs-attr">messages</span>: [
      { <span class="hljs-attr">role</span>: <span class="hljs-string">"system"</span>, <span class="hljs-attr">content</span>: <span class="hljs-string">"You are an SEO assistant."</span> },
      { <span class="hljs-attr">role</span>: <span class="hljs-string">"user"</span>, <span class="hljs-attr">content</span>: <span class="hljs-string">`Analyze the following page info: <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(pageData)}</span>`</span> }
    ]
  })
});
</code></pre>
<p>For example, after building this basic analyzer, I expanded it into a full-featured <a target="_blank" href="https://rankingsfactor.com/extension">RankingsFactor AI SEO Extension</a> which combines this same foundation with:</p>
<ul>
<li><p>AI-generated keyword suggestions</p>
</li>
<li><p>Metadata improvement recommendations</p>
</li>
<li><p>Automatic screenshot capture</p>
</li>
<li><p>Page freshness detection</p>
</li>
</ul>
<p>This demonstrates how a simple developer project can evolve into a powerful, production-ready tool.</p>
<h3 id="heading-2-detect-missing-seo-tags">🔍 2. Detect Missing SEO Tags</h3>
<p>You can check for missing tags like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> missingTags = [];
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'meta[name="description"]'</span>)) missingTags.push(<span class="hljs-string">"description"</span>);
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'meta[property="og:title"]'</span>)) missingTags.push(<span class="hljs-string">"og:title"</span>);
</code></pre>
<h3 id="heading-3-add-screenshot-or-report-export">🖼️ 3. Add Screenshot or Report Export</h3>
<p>Use the <code>chrome.tabs.captureVisibleTab()</code> API to take a screenshot, or generate a downloadable HTML/JSON report.</p>
<h2 id="heading-step-9-publish-to-the-chrome-web-store">🧭 Step 9: Publish to the Chrome Web Store</h2>
<p>Once you’ve tested your extension, visit <a target="_blank" href="https://chrome.google.com/webstore/devconsole">chrome.google.com/webstore/devconsole</a>. You’ll need to pay a one-time $5 developer registration fee, then you can upload your extension as a ZIP file. Make sure you write a clear, helpful description before submitting your extension for review.</p>
<h2 id="heading-final-thoughts">✅ Final Thoughts</h2>
<p>In this tutorial, you learned:</p>
<ul>
<li><p>How Chrome extensions communicate between scripts and web pages</p>
</li>
<li><p>How to safely extract DOM data</p>
</li>
<li><p>How to display structured information in a popup UI</p>
</li>
<li><p>How to extend browser tools with AI for smarter analysis</p>
</li>
</ul>
<p>Browser extensions are an incredible way to bring web automation, analysis, and creativity directly into your workflow. Whether you’re analyzing pages, improving accessibility, or experimenting with AI, you now have the foundation to build anything you imagine.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use React Developer Tools – Explained With Examples ]]>
                </title>
                <description>
                    <![CDATA[ Traditional browser developer tools are designed to inspect and debug web pages by interacting with your HTML, CSS, and JavaScript code. However, you can't use them to inspect and debug React applications efficiently due to the nature of React. This ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-react-devtools/</link>
                <guid isPermaLink="false">66bc4d2460ad5c1520c1668f</guid>
                
                    <category>
                        <![CDATA[ devtools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Matéu.sh ]]>
                </dc:creator>
                <pubDate>Mon, 06 May 2024 20:12:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/React-Devtools.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Traditional browser developer tools are designed to inspect and debug web pages by interacting with your HTML, CSS, and JavaScript code. However, you can't use them to inspect and debug React applications efficiently due to the nature of React.</p>
<p>This is where the React Developer Tools, AKA React DevTools comes into play. It allows you to inspect and debug your React applications by providing access to the components, states, hooks, props, what renders what, and more.</p>
<p>This article will show you how to use React DevTools by focusing on components, props, and state inspection. We'll also examine how to use it to enhance application performance.</p>
<p>For demonstration, we'll use the 2048 game code. You can grab it in <a target="_blank" href="https://github.com/mateuszsokola/2048-in-react">this GitHub repository</a>.</p>
<h2 id="heading-how-to-install-react-developer-tools">How to Install React Developer Tools</h2>
<p>Installing the React developer tools extension for your browser is the most common way to use it. </p>
<p>If you use Chrome, visit the Chrome Webstore and search for "React", then select "React Developer Tools" and click the "<em>Add to Chrome</em>" button to install it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-11.14.42.png" alt="Image" width="600" height="400" loading="lazy">
<em>React Devtools in Chrome Web Store</em></p>
<p>React DevTools is also available as a standalone electron app, an NPM package, and an add-on for both Edge and Firefox browsers. If you use the Safari browser, consider using the NPM package.</p>
<p>If you use the extension on Chrome but want to migrate your data to either Edge and Firefox, it will be automatically installed for you!</p>
<h2 id="heading-how-to-navigate-the-react-developer-tools-interface">How to Navigate the React Developer Tools Interface</h2>
<p>After installing the DevTools as an extension, open your browser console and you should see two additional tabs – Components and Profiler.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-25.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google Chrome with React DevTools extension</em></p>
<p>The Components tab displays a tree view of the components in your application. It also gives you access to the hooks and props in each component.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-11.22.31.png" alt="Image" width="600" height="400" loading="lazy">
<em>Components tab in React DevTools</em></p>
<p>The Profiler tab allows you to analyze the runtime performance of your applications and identify costly re-renders or performance bottlenecks. From there, you can import and export recorded performance sections and see how long a component renders or why it re-renders.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-11.23.32.png" alt="Image" width="600" height="400" loading="lazy">
<em>Profiler tab in React DevTools</em></p>
<p>If you click the gear icon on the right side in any of the tabs, you should see a pop-up with 4 tabs – General, Debugging, Components, and Profiler.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-11.24.24.png" alt="Image" width="600" height="400" loading="lazy">
<em>React DevTools settings</em></p>
<p>In the 4 tabs, you can adjust settings related to theme, display, debugging options, component filters, and recording settings for the profiler.</p>
<h2 id="heading-how-to-inspect-react-components-with-devtools">How to Inspect React Components with DevTools</h2>
<p>In the Components tab, you can select a component and inspect it, just like you'd do with HTML elements in a traditional browser's dev tools.</p>
<p>To do that, click the select icon on the top-left corner, then select any part of the app to see the component that represents it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/devtools-1--1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Inspecting components in React DevTools</em></p>
<p>As you make changes that involve adding something, new components will be added to the tree.  </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/devtools-2.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Live component updates in React DevTools</em></p>
<p>On the right-hand side in the Components tab are the <code>props</code>, <code>hooks</code>, <code>renderer</code>, and the <code>source</code> for any component you select in the tree.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-26.png" alt="Image" width="600" height="400" loading="lazy">
<em>Component details in React DevTools</em></p>
<h2 id="heading-how-to-explore-component-state-and-props">How to Explore Component State and Props</h2>
<p>Remember that when you select a component in the tree, the state and props in that component are available on the right-hand side.</p>
<p>In the screenshot below, I have selected a <code>Tile</code> component for you to see the props:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-27.png" alt="Image" width="600" height="400" loading="lazy">
<em>Tile component selected</em></p>
<p>You can see that the <code>Tile</code> component has <code>id</code>, <code>position</code>, and <code>value</code> properties. From here, you can add a new prop and edit the existing props.</p>
<p>For example, I just changed a <code>value</code> prop from <code>2</code> to <code>4</code> and it reflected in the UI in real-time:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/devtools-3.gif" alt="Image" width="600" height="400" loading="lazy">
<em>change value from 2 to 4</em></p>
<p>You can also make changes to a piece of state. For instance, the scorecard you can see in the UI is a piece of state in the <code>GameProvider</code> context. It updates your score as you play the game.</p>
<p>You can select the <code>GameProvider</code> context, look for the <code>score</code> state, and change it to something else:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/devtools-4.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Change score state</em></p>
<h2 id="heading-how-to-debug-react-applications-with-react-devtools">How to Debug React Applications with React DevTools</h2>
<p>The traditional browser developer tools is good for debugging your HTML, CSS, and JavaScript code, but it has limitations concerning debugging React applications.</p>
<p>This is the primary reason React DevTools was created in the first place, as it has the essential built-in features that can show you everything you need to debug your React apps.</p>
<p>One of the errors the browser can help you debug is a reference error. For instance, if there's an error in any of your components, the browser can show you the error message and the line affected.</p>
<p>For example, I've forced an error by changing <code>cells</code> to <code>cell</code> on line 62 in the <strong>board.tsx</strong> file of the app. This is what the error message looks like in the browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-12.08.50.png" alt="Image" width="600" height="400" loading="lazy">
<em>Reference Error in React 19</em></p>
<p>You can then go to the line of code where the error occurred and make the necessary adjustments so the app can run again.</p>
<p>React DevTools also shows you a reference error and the component in which it occurs.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-12.11.19.png" alt="Image" width="600" height="400" loading="lazy">
<em>Reference Error in React DevTools</em></p>
<h2 id="heading-how-react-devtools-takes-debugging-to-the-next-level">How React DevTools Takes Debugging to the Next Level</h2>
<p>In the Components tab, above the items on the right-hand side, are iconized buttons you can use to:</p>
<ul>
<li>Force the selected component to an errored state </li>
<li>Inspect the matching DOM element</li>
<li>Suspend the selected component</li>
<li>Log the component data to the console</li>
<li>View the source code for the elements in the selected component</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-28.png" alt="Image" width="600" height="400" loading="lazy">
<em>Component utilities in React DevtTools</em></p>
<p>For example, if the tiles in the game are not showing as they should, it's probably a styling issue.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-12.16.43.png" alt="Image" width="600" height="400" loading="lazy">
<em>Unstyled tiles in 2048 Game</em></p>
<p>This particular error will not stop your app from running, so the best way to debug it is to use React DevTools instead of looking through your code, especially if it's large.</p>
<p>You can select the <code>Tile</code> component and log its data to the console. When you do this, the <code>props</code>, <code>hooks</code>, and <code>nodes</code> of that component will be logged for you.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-29.png" alt="Image" width="600" height="400" loading="lazy">
<em>Utility allowing to log component data to the console in React DevTools</em></p>
<p>To see the component's data, you have to switch to the console tab and inspect the <code>nodes</code> to see what might have gone wrong.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-12.21.11.png" alt="Image" width="600" height="400" loading="lazy">
<em>Component data printed in the console React DevTools</em></p>
<p>In the image above,it shows that there is a <code>div</code> element with an undefined <code>className</code>. This tells you that you've misspelt a <code>className</code> value, so you need to go back to your code and correct it.</p>
<p>If the error you're getting has to do with <code>props</code> or <code>hooks</code>, then you need to open up any of them to see what went wrong.</p>
<p>You can also look through the source code of any component causing an issue. For instance, if the scoreboard is not showing as it has to, select the component and click the "View source code for this element" icon.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-30.png" alt="Image" width="600" height="400" loading="lazy">
<em>View source of this component utility in React DevTools</em></p>
<p>After the source code is displayed, you can step through the end of each line. Any line end that is red when you do that is the one causing the error.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/devtools-5.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can then go back to your editor and make the necessary changes on that line.</p>
<h2 id="heading-performance-analysis-with-react-devtools">Performance Analysis with React DevTools</h2>
<p>Doing performance analysis with React can help you understand the efficiency of your application and identify any performance bottlenecks. This is what the Profiler tab lets you do.</p>
<p>To do this, switch to the Profiler tab and click the "Start profiling" icon to start recording.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-31.png" alt="Image" width="600" height="400" loading="lazy">
<em>Record button in the Profile tab of React DevTools</em></p>
<p>Perform the actions in your app you want to analyze. This could be page loads, user interactions like button clicks, swiping, or dynamic content loading. When you're done, click "Stop" to end the recording.</p>
<p>The Profiler will then display a flame graph and a list of commits. Each commit represents a render phase of your React application. Components that take longer to render will have wider bars.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/devtools-6.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can then select a specific commit to view detailed information about the render performance of components during that commit:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Screenshot-2024-05-06-at-12.28.57-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Profiling results in React DevTools</em></p>
<p>You can also download the profiling session, or import a profiling session. This means you can share the session with your teammates.</p>
<h2 id="heading-common-issue-and-solution-how-to-fix-react-devtools-not-showing">Common Issue and Solution: How to Fix React DevTools Not Showing</h2>
<p>If DevTools fails to show up, it could be because it doesn't have access to the React sites you're viewing in the browser.</p>
<p>To fix this, type <code>chrome://extensions/</code> into the address bar and hit enter, then search for the extension and make sure it's toggled on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-32.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to enable React DevTools extension in Google Chrome</em></p>
<p>If that doesn't fix the issue, click the "Details" button and make sure you grant an "On all sites" access under the "Site access" option</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Group-33.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to change extension's site access settings in Google Chrome</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>From inspecting the component hierarchy and modifying state and props to profiling performance and understanding complex re-renders, React Developer Tools offers a comprehensive set of features that can improve the quality of your React applications.</p>
<p>Whether you're a beginner aiming to have a better understanding of the inner workings of React, or an experienced developer looking to optimize your applications, investing the time to master React Developer Tools will be profitable in your development processes.</p>
<h2 id="heading-learn-react-and-next-js">Learn React and Next JS</h2>
<p>Are you ready to dive deep into React and start creating real-world applications? Enroll in my <a target="_blank" href="https://assets.mateu.sh/r/fcc-react-devtools">React and Next JS course on Udemy</a>! You'll learn through hands-on coding as we build an incredible 2048 game from scratch with cool animations.</p>
<p>Join now and start your journey to becoming an employable React developer!</p>
<p><a target="_blank" href="https://assets.mateu.sh/r/fcc-react-devtools"><img src="https://assets.mateu.sh/assets/fcc-react-devtools" alt="Learn Next.js and React 19 to Create 2048 Game From Scratch" width="600" height="400" loading="lazy"></a><br><em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Chrome DevTools – Simple Strategies for Smarter Web Development ]]>
                </title>
                <description>
                    <![CDATA[ As a web developer, there are many tools out there – in addition to your code editor – that can make you more efficient.  It doesn't matter if you're just starting out or have been coding for years. Knowing how to effectively use Developer Tools (Dev... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chrome-devtools/</link>
                <guid isPermaLink="false">66c5a334215f782a032b1cb7</guid>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ debugging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ devtools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Problem Solving ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ophy Boamah ]]>
                </dc:creator>
                <pubDate>Thu, 15 Feb 2024 16:12:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/ChromeDevTools-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a web developer, there are many tools out there – in addition to your code editor – that can make you more efficient. </p>
<p>It doesn't matter if you're just starting out or have been coding for years. Knowing how to effectively use Developer Tools (DevTools for short) can significantly boost your development process. You can edit pages on the fly, quickly spot issues, and deeply understand your site's performance. </p>
<p>All major browsers have their own DevTools that let you examine the code of a webpage, evaluate its metrics, and run some tests alongside. This article will discuss Chrome's DevTools, as it's the industry standard.</p>
<h2 id="heading-table-of-contents">Table of contents:</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-chrome-devtools">What is Chrome DevTools?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-open-chrome-devtools">How to Open Chrome DevTools</a></li>
<li><a class="post-section-overview" href="#heading-keyboard-shortcuts-for-easy-navigation">Keyboard shortcuts for Easy Navigation</a></li>
<li><a class="post-section-overview" href="#heading-key-chrome-devtools-features">Key Chrome DevTools Features</a></li>
<li><a class="post-section-overview" href="#heading-practical-devtools-use-cases">Practical DevTools Use Cases</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h1 id="heading-what-is-chrome-devtools">What is Chrome DevTools?</h1>
<p>Chrome DevTools is a set of tools that are essential for diagnosing and solving web development challenges, directly within the Google Chrome browser. </p>
<p>It gives you direct access to a website's inner workings - to inspect HTML and CSS, debug JavaScript, analyze performance, and see the immediate impact of your code, all in realtime. </p>
<p>This direct access to a website's inner workings is crucial for diagnosing issues quickly and efficiently, ensuring your web applications are both performant and bug-free.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/DevToolsScreenshots-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>A grid of elements, console, performance and network panels screenshots</em></p>
<h1 id="heading-how-to-open-chrome-devtools">How to Open Chrome DevTools</h1>
<p>To open DevTools in your Chrome browser, you can either:</p>
<ol>
<li>Right-click on any webpage and select inspect from the list of options.</li>
<li>Use the shortcut (command + option + I on Mac or control + shift + I on Windows). </li>
<li>Click the three dot icon next to your profile picture on your Chrome browser, choose 'More Tools' and 'Developer Tools' from the second option box.</li>
</ol>
<p>It usually opens in a split screen interface, either below your current webpage or beside it. Once open, its features line up as tabs at the top of the DevTools window. These tabs include: Elements, Console, Source, Network, Application, Security, Memory, Performance, Audits.</p>
<h2 id="heading-keyboard-shortcuts-for-easy-navigation">Keyboard Shortcuts for Easy Navigation</h2>
<ol>
<li>Use Cmd or Ctrl + Shift + C to open the Elements panel</li>
<li>Use Cmd or Ctrl + Shift + J to open the Console panel</li>
<li>Use Cmd or Ctrl + ] to move forward to the next panel </li>
<li>Use Cmd or Ctrl + [ to move back to the previous panel </li>
</ol>
<h1 id="heading-key-chrome-devtools-features">Key Chrome DevTools Features</h1>
<p>DevTools is packed with features essential for web developers to streamline various aspects of their workflow. Let's look at a few of them in some detail now.</p>
<h2 id="heading-elements-panel">Elements Panel</h2>
<p>This panel is used for inspecting and modifying the HTML and CSS of a webpage in real-time, which is great for debugging layout issues or experimenting with new styles before applying them in your actual code. You also get to see how the DOM (Document Object Model) is structured. </p>
<p>Imagine fine-tuning your website's footer appearance (background color, font size) directly in your browser and seeing the results instantly. </p>
<p>With DevTools open, click on the Elements tab to access it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/elpanel-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of Chrome DevTools' Elements panel</em></p>
<h2 id="heading-console-panel">Console Panel</h2>
<p>This panel serves as your interactive playground for JavaScript within the browser. Whether you're tracking down an elusive bug with a quick <code>console.log()</code> or experimenting with DOM elements, in the Console panel you can test snippets of JavaScript and view any logs or errors in the currently loaded webpage. </p>
<p>To use it, simply open DevTools and select the "Console" tab or use the shortcut (option + command + J on Mac or contrl + shift + J on Windows).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/clpanel-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of Chrome DevTools' Console panel</em></p>
<h2 id="heading-network-panel">Network Panel</h2>
<p>This panel gives you an overview of all network activity on your webpage – from tracking every resource that is loaded to how your site communicates with servers. </p>
<p>If you've wondered why your website takes forever to load or why some API requests seem to vanish into thin air, the Network panel is your go-to as it provides insights into the success or failure of API calls. </p>
<p>To access it, open DevTools and navigate to the "Network" tab.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/netpanel-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of Chrome DevTools' Network panel</em></p>
<h2 id="heading-performance-panel">Performance Panel</h2>
<p>This panel is used for capturing and analyzing a website's performance metrics. It shows all the activities happening when interacting with a page. </p>
<p>When your web app starts to crawl under heavy usage, the Performance panel can pinpoint where the performance bottlenecks lie so that you can resolve these issues, ensuring your app runs smoothly. </p>
<p>With DevTools open, click on the "Performance" tab to use it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/perfpanel-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of Chrome DevTools' Performance panel</em></p>
<p>The above are only a handful of the panels available, but they're by far the most popular and must-knows. Using them properly will make your development processes more intuitive and rewarding.</p>
<h1 id="heading-practical-devtools-use-cases">Practical DevTools Use Cases</h1>
<p>In the following interactive examples, I intentionally created the mini project in Codepen <strong>with issues</strong> to simulate real-world debugging scenarios using Chrome DevTools. </p>
<p>I figured it'd be a great way to highlight the practical uses of certain DevTools panels and features in identifying bugs and troubleshooting right in the browser. </p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li>Chrome browser (<a target="_blank" href="https://support.google.com/chrome/answer/95346?hl=en&amp;co=GENIE.Platform%3DDesktop">Click this link to download</a>)</li>
<li>A basic understanding of HTML, CSS, and JavaScript</li>
<li><a target="_blank" href="https://codepen.io/ophyboamah/full/rNpZZwo">Codepen</a></li>
</ul>
<p></p><p>
  <span>See the Pen <a href="https://codepen.io/ophyboamah/pen/rNpZZwo">
  Modal Window</a> by Ophy Boamah (<a href="https://codepen.io/ophyboamah">@ophyboamah</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p><p></p>


<h2 id="heading-how-to-debug-html-and-css-with-the-elements-panel">How to Debug HTML and CSS with the Elements Panel</h2>
<p>Our mini project contains a modal that, upon clicking, should display a modal window with some important information. But there's a bug preventing this from happening. </p>
<p>This situation sets the stage for a practical demonstration of how you can use the Elements Panel to troubleshoot and resolve styling and structural issues.</p>
<pre><code>&lt;body&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"show-modal"</span>&gt;</span>Click me to learn a secret 🤫<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>

  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"modal hidden"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"close-modal"</span>&gt;</span><span class="hljs-symbol">&amp;times;</span><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hey Ophy here 👋🏾<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      I lead Women Who Code Frontend, a global remote community of 3,000+ women frontend devs and enthusiasts. Find us on beacons.ai/wwcodefrontend
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"overlay hidden"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
&lt;/body&gt;
</code></pre><pre><code class="lang-css"><span class="hljs-selector-class">.hidden</span> {
  <span class="hljs-attribute">display</span>: none;
}

<span class="hljs-selector-class">.modal</span> {
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">left</span>: <span class="hljs-number">50%</span>;
  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translate</span>(-<span class="hljs-number">50%</span>);
  <span class="hljs-attribute">width</span>: <span class="hljs-number">70%</span>;

  <span class="hljs-attribute">background-color</span>: white;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">6rem</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">3rem</span> <span class="hljs-number">5rem</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.3</span>);
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">10</span>;
}
</code></pre>
<p>In our modal's HTML code above, we've added the class name 'modal hidden' which has a corresponding styling with the CSS property of <code>display:none</code> that is set to hide the modal when the page is loaded initially and only display it when the button is clicked.</p>
<h3 id="heading-step-1-initial-inspection">✅ Step 1 - Initial inspection:</h3>
<p>Attempt to trigger the modal by clicking on the 'Click me to learn a secret' button. Since we've set that up not to work, right-click on the area where the modal should appear and choose "Inspect" to open DevTools' Elements Panel.</p>
<h3 id="heading-step-2-diagnose-visibility-issues">✅ Step 2 - Diagnose visibility issues:</h3>
<p>In the Elements Panel, locate the modal in the DOM to see that the modal is present but not visible. This confirms that the bug is caused within our CSS code <code>display: hidden</code>. </p>
<p>As soon as you click on the modal in the DOM, any corresponding CSS classes will be pulled up within Styles at the bottom section of the Elements panel. You can toggle some properties on and off or type others to see the effects in real-time.</p>
<p>Manually change the class name from <code>modal hidden</code> to <code>modal block</code> to trigger the right properties that'll cause the modal to show.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/modalblock.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of debugging the modal's HTML, CSS in Elements panel</em></p>
<h3 id="heading-step-3-center-the-modal">✅ Step 3 - Center the modal:</h3>
<p>Now the modal is visible, but it's displayed at the top – which is different from where we'd like it to be (that is, in the center of the page).</p>
<p>To change this, modify the <code>transform</code> property to <code>translate(-50%, -50%)</code> by adding the second <code>-50%</code> and ensure that <code>top: 50%</code>, and <code>left: 50%</code> are correctly set to center the modal on the screen.</p>
<h3 id="heading-step-4-enhance-the-appearance">✅ Step 4 - Enhance the appearance:</h3>
<p>You can go further to refine the modal's appearance by tweaking its <code>background-color</code>, <code>padding</code>, or other stylistic properties directly within the Styles to achieve the desired look and feel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/ChromeDevTools.gif" alt="Image" width="600" height="400" loading="lazy">
<em>A GIF fixing the modal in Chrome DevTools' Elements panel</em></p>
<h2 id="heading-debug-javascript-with-the-sources-panel">Debug JavaScript with the Sources Panel</h2>
<p>I added a bug in the JavaScript code of our modal mini project to prevent it from opening when the button is clicked. </p>
<p>In the real world, this would cause neither the open nor close commands to trigger any action, which would leave users unable to interact with the content and frustrated as a result. Let's troubleshoot and debug this issue in the Sources Panel.</p>
<p>In the code below, the openModal function is set to remove the indicated classes. However, this doesn't work because we deliberately misspelled <code>hidden</code>. </p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Introducing a bug: Incorrectly spelling 'hidden' as 'hiddn'</span>
<span class="hljs-keyword">const</span> openModal = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  modal.classList.remove(<span class="hljs-string">"hiddn"</span>); <span class="hljs-comment">// Intentional bug</span>
  overlay.classList.remove(<span class="hljs-string">"hidden"</span>);

  <span class="hljs-comment">// Fetch data from a real API and display in the modal</span>
};
</code></pre>
<h3 id="heading-step-1-set-up-breakpoints">✅ Step 1 - Set up breakpoints:</h3>
<p>Open Chrome DevTools and navigate to the Sources Panel. Here, find the JavaScript file that includes the modal functionality (in our example its pen.js). </p>
<p>The openModal function contains the logic for displaying the modal on the screen. This function will include a line where the modal element's class is manipulated to remove a "hidden" class. </p>
<p>Click on the number next to this code line in DevTools. A blue (or sometimes red, depending on the theme) icon appears next to the line number, indicating that a breakpoint has been set. This breakpoint will pause the execution of our JavaScript code as soon as it reaches this line.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/soscreenshot.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot of setting breakpoints the modal's JS in Sources panel</em></p>
<p>Breakpoints pause code execution at critical points, allowing you to inspect the current state of variables and understand the flow of execution. This step is crucial for identifying where the code deviates from expected behaviour.</p>
<h3 id="heading-step-2-examine-the-code-execution-flow">✅ Step 2 - Examine the code execution flow:</h3>
<p>With our breakpoint in place, try to open the modal by clicking on its button. Execution of our JavaScript code now pauses at our breakpoint, which enables us to step through the code line by line. </p>
<p>This is an opportunity to observe variables, function calls, look for anomalies such as misnamed functions, incorrect logic, or uncaught exceptions that could explain why the modal isn't working. </p>
<p>In our case it's because we intentionally misspelled the class name <code>hidden</code> as <code>hiddn</code>. Fix that in the code to get the modal working again.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/ChromeDevTools--2-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>A GIF troubleshooting the modal bug in Chrome DevTools' Elements panel</em></p>
<h2 id="heading-optimize-performance-with-the-network-panel">Optimize Performance with the Network Panel</h2>
<p>Here I've added a fetch function that makes an API call to a live endpoint (<a target="_blank" href="https://jsonplaceholder.typicode.com/posts/1"><code>https://jsonplaceholder.typicode.com/posts/1</code></a>). This is an excellent opportunity to explore the Network Panel's capabilities in diagnosing and understanding network-related problems.</p>
<p>From the code below, you can see that the openModal function doesn't only open the modal but also makes an API call to the <code>jsonplaceholder</code> endpoint to fetch some data. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> openModal = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  fetch(<span class="hljs-string">'https://jsonplaceholder.typicode.com/posts/1'</span>)
    .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())
    .then(<span class="hljs-function"><span class="hljs-params">json</span> =&gt;</span> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'modal-content'</span>).innerText = json.title)
    .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error loading the content:'</span>, error));
};
</code></pre>
<h3 id="heading-step-1-initiate-the-api-call">✅ Step 1 - Initiate the API call:</h3>
<p> On the modal project UI, click on the 'Click me to learn a secret' button. Though the modal does not visibly activate, because of the fetch logic within the openModal function, an API call will be made.</p>
<h3 id="heading-step-2-network-panel-inspection">✅ Step 2 - Network Panel Inspection:</h3>
<p>Ideally, your Network Panel should be open before clicking the button, but you can also reverse the steps. Detailed insights on your API request such as the request's method, status code, response and the time it took to complete, will be available under headers, preview, response, initiator and timing tabs respectively. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/netscreenshot.png" alt="Image" width="600" height="400" loading="lazy">
<em>A screenshot overview of API request in Network panel</em></p>
<h3 id="heading-step-3-simulating-network-conditions">✅ Step 3 - Simulating Network Conditions:</h3>
<p>Use the Network Panel's throttling feature to mimic various network speeds like offline or slow 3G to see how the API request behaves under constrained conditions. </p>
<p>From this you can compare how different network speeds can affect application performance. This will teach you the importance of optimizing data loading strategies to enhance user experience, especially on slower connections.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/ChromeDevTools--1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>A GIF observing API requests and responses in Chrome DevTools' Network panel</em></p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Bringing Chrome DevTools into your web development routine is not just about fixing bugs. It's about streamlining your workflow, making your sites more accessible, and boosting their performance. </p>
<p>Through our modal window mini-project, we've seen firsthand how DevTools can address a wide array of development challenges, but that’s merely scratching the surface of what it can do. </p>
<p>As you continue to explore its capabilities and familiarize yourself with its features, you'll find it's an invaluable companion on your web development journey – designed to make your development process not just faster, but also more rewarding.</p>
<ul>
<li><a target="_blank" href="https://developer.chrome.com/docs/devtools">The Official Chrome DevTools documentation</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/learn-how-to-use-the-chrome-devtools-to-troubleshoot-websites/">How to use the Chrome DevTools to troubleshoot websites</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
