<?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[ Browsers - 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[ Browsers - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 20 May 2026 22:46:58 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/browsers/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Design Accessible Browser Extensions ]]>
                </title>
                <description>
                    <![CDATA[ Building a browser extension is easy, but ensuring that it’s accessible to everyone takes deliberate care and skill. Your extension might fetch data flawlessly and have a beautiful interface, but if screen reader users or keyboard navigators can’t us... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-design-accessible-browser-extensions/</link>
                <guid isPermaLink="false">68c169e7d950044818727fd6</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Browser Extension ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ophy Boamah ]]>
                </dc:creator>
                <pubDate>Wed, 10 Sep 2025 12:07:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757460414092/f3a9f3ec-f520-4627-b839-a28f15574ba6.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building a browser extension is easy, but ensuring that it’s accessible to everyone takes deliberate care and skill.</p>
<p>Your extension might fetch data flawlessly and have a beautiful interface, but if screen reader users or keyboard navigators can’t use it, you’ve unintentionally excluded many potential users.</p>
<p>In this article, we will audit a Chrome browser extension for accessibility issues and transform it into an inclusive experience that works for everyone.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-why-accessibility-matters-in-browser-extensions">Why Accessibility Matters in Browser Extensions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-perform-manual-browser-extension-accessibility-tests">How to Perform Manual Browser Extension Accessibility Tests</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-browser-extension-accessibility-improvements">How to Implement Browser Extension Accessibility Improvements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-perform-automated-browser-extension-accessibility-tests">How to Perform Automated Browser Extension Accessibility Tests</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-accessible-browser-extensions">Best Practices for Accessible Browser Extensions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-why-accessibility-matters-in-browser-extensions">Why Accessibility Matters in Browser Extensions</h2>
<p>Every click in your browser extension is an opportunity to empower users or exclude them if accessibility isn’t part of your design.</p>
<p>Browser extensions face unique accessibility challenges, as they must inject functionality into existing web pages while maintaining their own accessible interfaces - a dual responsibility that can introduce potential barriers. For example, a popup that traps keyboard users or fails to communicate with screen readers can render an extension unusable.</p>
<p>With over one billion people living with disabilities, according to the World Health Organization, accessible design unlocks a vast user base and creates better experiences for everyone.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757242166628/da2f87e2-5903-4bae-a2f4-071b2a339c69.png" alt="An infographic showing browser extension common accessibility barriers" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>For browser extensions, accessibility barriers commonly emerge as:</p>
<ul>
<li><p><strong>Keyboard navigation dead-ends</strong>: Popups and interfaces that trap or exclude keyboard users.</p>
</li>
<li><p><strong>Silent interactions</strong>: Missing labels and descriptions, like a button with only an icon announced as “unlabelled button” by screen readers, leaving users guessing about its purpose.</p>
</li>
<li><p><strong>Unannounced dynamic content updates</strong>: Content changes that occur without assistive technology awareness, such as a quote updating without notifying screen readers of the change, including missing feedback for loading states or errors</p>
</li>
<li><p><strong>Context integration conflicts</strong>: Extensions modifying existing web pages can mistakenly break the page's accessibility features or introduce elements that clash with established navigation patterns</p>
</li>
</ul>
<p>By understanding these barriers, developers can take targeted steps to test and improve their extensions’ accessibility.</p>
<h2 id="heading-how-to-perform-manual-browser-extension-accessibility-tests">How to Perform Manual Browser Extension Accessibility Tests</h2>
<p>While automated tools catch obvious issues, manual testing reveals the real user experience. Here's how to systematically evaluate your extension's accessibility.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">You can use any unpublished browser extension to follow along. For this test, we’ll be using the <a target="_self" href="https://www.freecodecamp.org/news/how-to-build-an-advice-generator-chrome-extension-with-manifest-v3/">browser extension built in this article</a>, which uses <a target="_self" href="https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db?via=ophyboamah">this Advice generator app design</a>.</div>
</div>

<h3 id="heading-keyboard-navigation-test">Keyboard Navigation Test</h3>
<p>Disconnect your mouse and try to use your extension completely with the keyboard only. Navigate using <code>Tab</code> to move between elements, <code>Enter</code> or <code>Space</code> to activate buttons, and arrow keys within components. </p>
<ul>
<li><p>Is it always clear which element has focus?</p>
</li>
<li><p>Can you activate buttons with <code>Enter</code> or <code>Space</code> as expected?</p>
</li>
<li><p>Can users exit modal dialogs or dropdown menus?</p>
</li>
</ul>
<p>If you encounter any dead-ends or confusion points, keyboard users will face the same barriers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757242828152/b1555a79-a810-4d02-a995-6bf101ca2564.png" alt="An screenshot of an advice interface with a focused button " class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-screen-reader-evaluation">Screen Reader Evaluation</h3>
<p>Use your operating system's built-in screen reader to navigate your extension and listen to what is announced. On macOS, enable VoiceOver; on Windows, use Narrator; on Linux, try Orca. </p>
<ul>
<li><p>Does each element’s purpose come through clearly, such as a button announced as “Generate new advice” rather than just “button”?</p>
</li>
<li><p>Are headings, lists, and other structures properly conveyed?</p>
</li>
<li><p>Do users understand when content is loading, selected, or has changed?</p>
</li>
</ul>
<p>This testing phase often reveals the gap between what you intended to communicate and what actually reaches users.</p>
<h3 id="heading-visual-accessibility-review">Visual Accessibility Review</h3>
<p>Examine your extension in different visual contexts. Use developer tools, like WebAIM’s Contrast Checker, to verify that text meets WCAG’s 4.5:1 contrast ratio for readability. Test how your extension appears in system high-contrast settings. Ensure:</p>
<ul>
<li><p>Functionality remains usable at 200% zoom.</p>
</li>
<li><p>Information isn’t conveyed through colour alone, such as using text labels alongside colour-coded indicators.</p>
</li>
</ul>
<p>These manual tests will uncover critical accessibility issues, paving the way for targeted improvements to make your extension inclusive.</p>
<h2 id="heading-how-to-implement-browser-extension-accessibility-improvements">How to Implement Browser Extension Accessibility Improvements</h2>
<p>Imagine refreshing a page without knowing it happened or clicking a button with no clear purpose. The manual tests performed above revealed that's the experience for screen reader users of our extension among these three key accessibility issues:</p>
<ul>
<li><p><strong>Missing button label</strong>: The dice button only has an image with alt text “Dice icon,” which lacks the context screen readers need</p>
</li>
<li><p><strong>Silent dynamic updates</strong>: When new advice loads, screen readers don't know the content has changed</p>
</li>
<li><p><strong>No loading states</strong>: When fetching advice, users receive no feedback that something is happening</p>
</li>
</ul>
<p>Let's address the issues before conducting automated tests.</p>
<h3 id="heading-how-to-address-missing-button-label-and-alt-text">How to Address Missing Button Label and Alt text</h3>
<p>We’ll add <code>aria-label</code> to clearly explain the button's purpose and provide descriptive alt text for the icon. The <code>role="presentation"</code> attribute ensures the image is treated as decorative by screen readers.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!--Before: Unclear Button Purpose and icon alt text--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dice-button"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"generate-advice-btn"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/icons/icon-dice.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Dice icon"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-comment">&lt;!--After: Clear, Accessible Button and icon alt text--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dice-button"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"generate-advice-btn"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Generate new advice"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/icons/icon-dice.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"A dice icon with green background"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"presentation"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-address-silent-dynamic-updates">How to Address Silent Dynamic Updates</h3>
<p>We’ll add <code>aria-live="polite"</code> for screen readers to announce new advice and <code>aria-atomic="true"</code> to ensure that the entire quote is read. That is:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!--Before: Silent Dynamic Updates--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"advice-quote"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"advice-quote"</span>&gt;</span>
    "It is easy to sit up and take notice, what's difficult is getting up and taking action."
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-comment">&lt;!--After: Announced Content Changes--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"advice-quote"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"advice-quote"</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span> <span class="hljs-attr">aria-atomic</span>=<span class="hljs-string">"true"</span>&gt;</span>
    "It is easy to sit up and take notice, what's difficult is getting up and taking action."
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-address-no-loading-states">How to Address No Loading States</h3>
<p>We’ll add a <code>setLoadingState</code> function to provide loading indicators, ensuring screen reader users are notified when content is being fetched:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Before: No Loading Feedback</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requestNewAdvice</span>(<span class="hljs-params"></span>) </span>{
  chrome.runtime.sendMessage({ <span class="hljs-attr">action</span>: <span class="hljs-string">"fetchAdvice"</span> }, <span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
    <span class="hljs-comment">// No loading indicators...</span>
  });
}

<span class="hljs-comment">// After: Accessible Loading States</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requestNewAdvice</span>(<span class="hljs-params"></span>) </span>{
  setLoadingState(<span class="hljs-literal">true</span>); 
  chrome.runtime.sendMessage({ <span class="hljs-attr">action</span>: <span class="hljs-string">"fetchAdvice"</span> }, <span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
    setLoadingState(<span class="hljs-literal">false</span>);
    <span class="hljs-comment">// Handle response with proper announcements...</span>
  });
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setLoadingState</span>(<span class="hljs-params">isLoading</span>) </span>{
  <span class="hljs-keyword">if</span> (isLoading) {
    <span class="hljs-comment">// Disable button and show loading text</span>
    generateAdviceBtn.disabled = <span class="hljs-literal">true</span>;
    generateAdviceBtn.setAttribute(<span class="hljs-string">'aria-label'</span>, <span class="hljs-string">'Loading new advice...'</span>);
    <span class="hljs-comment">// Show loading text in the advice quote element</span>
    adviceQuoteElement.textContent = <span class="hljs-string">"Loading new advice..."</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Re-enable button</span>
    generateAdviceBtn.disabled = <span class="hljs-literal">false</span>;
    generateAdviceBtn.setAttribute(<span class="hljs-string">'aria-label'</span>, <span class="hljs-string">'Generate new advice'</span>);
  }
}
</code></pre>
<p>With the manual testing issues addressed, we can now move on to performing an automated test of the same extension.</p>
<h2 id="heading-how-to-perform-automated-browser-extension-accessibility-tests">How to Perform Automated Browser Extension Accessibility Tests</h2>
<p>Manual testing provides crucial insights, but automated tools can efficiently catch common issues and provide ongoing monitoring. </p>
<p>This <a target="_blank" href="https://extensiona11ychecker.vercel.app/">Extension Accessibility Checker</a> simplifies testing by analyzing browser extension interfaces, such as popups and content scripts, for WCAG compliance, addressing unique challenges like popup constraints and content injection conflicts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757239257443/42918662-1465-4c01-8f07-ada5d9adb174.gif" alt="A GIF showing how to test an extension zip file with the Extension accessibility checker tool" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>To use the Extension Accessibility Checker:</p>
<ol>
<li><p>Compress your browser extension folder into a .zip file</p>
</li>
<li><p>Upload the .zip file on <a target="_blank" href="https://extensiona11ychecker.vercel.app/">https://extensiona11ychecker.vercel.app/</a></p>
</li>
<li><p>Review the generated report for specific accessibility violations and implement suggested fixes </p>
</li>
</ol>
<p>As shown in the GIF above, this workflow helps establish accessibility as a routine part of your development process rather than an afterthought.</p>
<p>With automated testing in place, let’s explore best practices to ensure that your extension remains accessible throughout development.</p>
<h2 id="heading-best-practices-for-accessible-browser-extensions">Best Practices for Accessible Browser Extensions</h2>
<p>We've transformed our <a target="_blank" href="https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db?via=ophyboamah">sample advice-generating browser extension</a> from a functional but inaccessible tool into an inclusive one that works for everyone. </p>
<p>Based on our improvements, here are four key principles for designing accessible browser extensions:</p>
<ol>
<li><h3 id="heading-semantic-html-and-clear-descriptive-labels">Semantic HTML and Clear, Descriptive Labels</h3>
</li>
</ol>
<p>Always start with proper HTML structure, using appropriate elements (for example, for a “Generate Advice” action, proper heading hierarchy) before adding ARIA attributes.</p>
<p>Ensure that every interactive element has a clear purpose via <code>aria-label</code>, <code>aria-labelledby</code>, or visible text that explains its action.</p>
<ol start="2">
<li><h3 id="heading-clear-communication-at-every-step">Clear Communication at Every Step</h3>
</li>
</ol>
<p>Every interactive element must convey its purpose effectively. Users need to understand:</p>
<ul>
<li><ul>
<li><p>What’s happening (for example, “Loading new advice…” for loading states)</p>
<ul>
<li><p>What went wrong (for example, “Failed to load advice” for errors)</p>
</li>
<li><p>What changed (for example, aria-live regions for updated content)</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol start="3">
<li><h3 id="heading-complete-keyboard-accessibility">Complete Keyboard Accessibility</h3>
</li>
</ol>
<p>All functionality must be available through keyboard navigation. This requires testing with <code>Tab</code>, <code>Enter</code>, <code>Space</code>, and arrow keys as appropriate.</p>
<p>Provide clear and thoughtful focus indicators that move predictably through your interface with obvious ways to exit modals or complex interactions.</p>
<ol start="4">
<li><h3 id="heading-user-preferences-and-content-script-considerations">User Preferences and Content Script Considerations</h3>
</li>
</ol>
<p>Respect user choices by supporting system font size settings and not overriding user-defined colour schemes unnecessarily.</p>
<p>When your extension modifies existing web pages, make sure you don't break the page's established accessibility features, focus management and navigation patterns. Ensure any new elements you inject follow accessibility standards.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As we’ve seen with our <a target="_blank" href="https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db?via=ophyboamah">advice-generating extension</a>, addressing accessibility issues transforms a functional tool into an inclusive one.</p>
<p>However, while fixing issues in existing extensions is helpful, the most effective approach is letting accessibility guide your design and development decisions from the first line of code.</p>
<p>When starting your next browser extension project, ask:</p>
<ul>
<li><p>How would someone navigate this using only a keyboard?</p>
</li>
<li><p>Is the purpose of every interactive element immediately clear to screen readers?</p>
</li>
<li><p>How will users understand what's happening during loading states?</p>
</li>
</ul>
<p>Here are some helpful resources</p>
<ul>
<li><p><a target="_blank" href="https://developer.chrome.com/docs/extensions/mv3/a11y/">Chrome Extension Accessibility Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://extensiona11ychecker.vercel.app/">Extension Accessibility Checker</a></p>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/WCAG21/quickref/">Web Content Accessibility Guidelines (WCAG) 2.1</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Boost Your Productivity With Cross-Browser DevTools Features ]]>
                </title>
                <description>
                    <![CDATA[ Building cross-browser web applications can be a difficult task, as many browsers offer few debugging tools that often vary between them. Fortunately, today most browsers support modern standards and provide helpful features for developers. Major bro... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/cross-browser-devtools-features/</link>
                <guid isPermaLink="false">66ff217ffdbf645a22d41640</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Uma Victor ]]>
                </dc:creator>
                <pubDate>Thu, 03 Oct 2024 22:58:07 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/JySoEnr-eOg/upload/e3e1bb6fdf9c408f7506093587114629.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building cross-browser web applications can be a difficult task, as many browsers offer few debugging tools that often vary between them. Fortunately, today most browsers support modern standards and provide helpful features for developers.</p>
<p>Major browsers, such as Chrome, Firefox, and Edge, continuously update their developer tools, with each update potentially bringing new features to web developers. These new features increase the ease of use by adding intuitive UIs, more advanced debugging, and enhanced performance analysis tools.</p>
<p>Staying up to date with these changes lets you use your browser <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Tools_and_setup/What_are_browser_developer_tools">DevTools</a> to its fullest potential to make your workflow easier and speed up the delivery of your web applications.</p>
<h2 id="heading-table-of-content">Table of Content</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-use-scroll-into-view-in-devtools">How to Use Scroll Into View in DevTools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-console-shortcuts-in-devtools">How to Use Console Shortcuts in DevTools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-block-resource-request-for-website-testing-in-devtools">How to Block Resource Request for Website Testing in DevTools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-edit-and-resend-network-request-in-devtools">How to Edit and Resend Network Request in DevTools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-detect-unused-source-code-in-devtools">How to Detect Unused Source Code in DevTools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-enable-accessibility-tree-in-devtools">How to Enable Accessibility Tree in DevTools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<p>In this article, we’ll discover some good cross-browser DevTools features and discuss how to use them.</p>
<p>Let’s get started!</p>
<h2 id="heading-how-to-use-scroll-into-view-in-devtools">How to Use Scroll Into View in DevTools</h2>
<p>When debugging, there may be a lot of HTML nodes to skim through to find out where your issue is. Most of the time, when you find the node, you won’t see it until you scroll to where it is on the page.</p>
<p>The Scroll Into View feature easily brings the DOM node into the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/Viewport_concepts">viewport</a> by right-clicking and selecting Scroll Into view in Chrome, Firefox, and Edge.</p>
<p>This feature saves a lot of time when debugging CSS issues or wanting to verify the correct placement of elements on a page, ensuring you can quickly locate elements on the page through the HTML nodes without needing to scroll through many lines of content manually.</p>
<p>In the image below, we are trying to find a <code>h2</code> element that is nested inside several layers of other elements.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727896981592/d326d8f8-6b79-4c0f-b7b6-d58d2f90344b.jpeg" alt="scroll into view devtools option" class="image--center mx-auto" width="1790" height="925" loading="lazy"></p>
<p>In the image above, instead of scrolling through the entire page to spot the <code>h2</code> element, we right-clicked and used the Scroll Into View feature to instantly bring the <code>h2</code> element into view. We can expand on this feature to do other things with the element when we have scrolled to it. We can tweak the CSS properties in real time via the styles panel and even find and fix layout issues.</p>
<h2 id="heading-how-to-use-console-shortcuts-in-devtools">How to Use Console Shortcuts in DevTools</h2>
<p>There are lots of shortcuts that can be used in the Console that allows you, as the developer, to debug faster. One of them is the <code>$_</code> shortcut. This shortcut returns the value of the most recent <a target="_blank" href="https://en.wikipedia.org/wiki/Expression_\(computer_science\)">expression</a> evaluated by the Console. Let’s say, for example, we have a multiplier function:</p>
<p>In the image below, you can see how the <code>$_</code> shortcut is used as a special variable in the browser Console to store the most recently evaluated expression:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727897503037/54aa559d-1ac2-4cf2-95f9-60f4d3c73520.png" alt="$_ shortcut used in the Console" width="2388" height="1142" loading="lazy"></p>
<p>Without the <code>$_</code> shortcut, you would have to either retype the entire function call or you might store the result in a variable like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> result = multiply(<span class="hljs-number">5</span>)
result(<span class="hljs-number">4</span>) <span class="hljs-comment">// returns 20</span>
</code></pre>
<p>In the code above, the <code>multiply(5)</code> function has to return a function and assign the function to result, which is then called with <code>4</code> as the parameter <code>result(4)</code>.</p>
<p>I'm sure you can see how this already introduces some redundancy and extra steps that can be cumbersome when you're dealing with more complex operations or when doing multiple steps of calculations. This is where the <code>$_</code> shortcut shines. When we run the <code>multiply(5)</code> code in the Console, a function is returned and stored in the <code>$_</code> variable by the Console, which we can access using the <code>$_</code> shortcut.</p>
<p>Another shortcut is using <code>$0</code> to access nodes from the Console. <code>$0</code> can be used to access the currently selected node in the DOM tree from within the Console. As you inspect a webpage with DevTools, you often browse the DOM tree in the Elements panel to find the element that you're interested in. Once you click on an element in this panel, DevTools internally keeps track of this element, and it becomes the currently selected element.</p>
<p>The <code>$0</code> is a shortcut that refers to the currently selected element in the Console, so you can manipulate it directly in the Console without writing a query to select it again.</p>
<p>The screenshot below shows how we can use <code>$0</code> in the Console to access the selected node in the DOM tree and change the background color to whatever we want.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727897399339/97ac2466-75b6-44ea-91b7-e0dee47e5ada.jpeg" alt="console shortcuts" width="2011" height="979" loading="lazy"></p>
<p>From the image above, we started by inspecting the desired element we wanted in the elements panel. Now, instead of querying the element again using <code>document.querySelector('#element')</code>, you can just use <code>$0</code> to manipulate it directly like this:</p>
<pre><code class="lang-javascript">$<span class="hljs-number">0.</span>style.backgroundColor = <span class="hljs-string">'lightblue'</span>;
</code></pre>
<p>This code changes the background color of the selected <code>&lt;div&gt;</code> to a gentle light blue. What really makes <code>$0</code> useful in this case is that it allows you to refer directly to the exact element you chose in the DOM, making sure that you're working with the correct element, even in cases where elements are dynamically generated or deeply nested.</p>
<h2 id="heading-how-to-block-resource-request-for-website-testing-in-devtools">How to Block Resource Request for Website Testing in DevTools</h2>
<p>The Block Resource Request DevTools feature is an important feature for web developers to test how their websites behave when specific resources cannot be loaded.</p>
<p>This feature enables you to simulate situations where an image, JavaScript, CSS, or an entire <a target="_blank" href="https://en.wikipedia.org/wiki/Domain_name">domain</a> becomes unreachable, and you get to see how your webpage would behave in that situation.</p>
<p>Resources requested by the browser aren’t always guaranteed to be downloaded, which can lead to unexpected experiences for users of your website. You can block requests to a resource on Chrome, Firefox, and Edge and test how your site behaves.</p>
<p>On Chrome and Edge:</p>
<ul>
<li><p>On the Network panel, right-click on the resource you want to block and select Block request URL.</p>
</li>
<li><p>Refresh the website, and the blocked resource won’t be downloaded and won’t affect the webpage.</p>
</li>
</ul>
<p>In the image below, we are using the Block request URL option in the Network tab to block a CSS request and see how the web page will look like if the selected CSS file fails to load.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727897541622/739a0a25-09bd-4e25-86c0-e5d1a0264131.png" alt="blocking requests" width="1391" height="710" loading="lazy"></p>
<p>From the image above, we can see all the network requests made by the webpage including requests for images, CSS files, JavaScript files, and so on. In my case I've filtered for just CSS files to be shown only.</p>
<p>From here, you can right-click on the CSS file in the Network panel and select Block request URL. This action will prevent the browser from loading the specific CSS file the next time the page is refreshed.</p>
<p>By blocking the request, we can watch out for weird behaviors and also measure how the absence of the blocked resource can affect the page load time and performance.</p>
<p>On Firefox:</p>
<ul>
<li><p>On the Network panel, right-click on the resource you want to block and select Block URL.</p>
</li>
<li><p>Reload the page.</p>
</li>
</ul>
<p>I’ve used this to test how my site behaves when I don’t load a particular JavaScript file. This feature can help developers debug issues that can arise when users disable JavaScript.</p>
<h2 id="heading-how-to-edit-and-resend-network-request-in-devtools">How to Edit and Resend Network Request in DevTools</h2>
<p>One of the coolest DevTools features is the ability to edit and resend <a target="_blank" href="https://en.wikipedia.org/wiki/Request%E2%80%93response">network requests</a> right in the browser. This feature can be really useful for debugging a network request problem. For example, scenarios where you’d want to see how changes to request parameters, headers, or body affect the response from the server, without having to make any changes to the frontend code or restarting the entire request process.</p>
<p>When making a network request, requests made to a backend service might fail or not respond with the intended data. It’s a pain to have to reload the whole page to retry the request, which is why the Edit and Resend feature is helpful.</p>
<p>In the Edge and Firefox browser, you can edit and resend a network request by right-clicking on the request you want to edit or resend and select Edit and Resend, just like in the image below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727897585816/68169a1f-987c-457a-a8ee-4335c2d88793.png" alt="Edit and replay" width="1020" height="649" loading="lazy"></p>
<p>In the image above, we tried to log into a website. When a user submits their credentials, the form sends a <code>POST</code> request to an API endpoint, <code>/auth/login</code>, with the user’s username and password.</p>
<p>Sometimes, the server may return a <code>400</code> Bad Request error, and for us to debug the error and find out why, we have to retry the request. We don't want to keep on filling out the form, so we use the Edit and Resend feature as shown below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727897620865/48eeb4fa-4bc4-44fb-b274-a23c5b037e1d.png" alt="modify xhr requests" width="2036" height="1114" loading="lazy"></p>
<p>The image above is the network Console or a sidebar that will open when you click on Edit and Resend, showing the details of the request. Here, you can edit:</p>
<ul>
<li><p>URL: If necessary, you can modify the URL or add query parameters.</p>
</li>
<li><p>Headers: You might notice a missing or incorrect Content-Type header, which you can fix here.</p>
</li>
<li><p>Body: This is where you can adjust the payload, such as correcting the username or password fields.</p>
</li>
</ul>
<p>In Chrome browsers, the edit and resend feature only works for <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XHR</a> requests, and you can use it by right-clicking on the request and selecting replay.</p>
<h2 id="heading-how-to-detect-unused-source-code-in-devtools">How to Detect Unused Source Code in DevTools</h2>
<p>The Coverage tool in DevTools enables developers to spot areas of their JavaScript and CSS files that remain unused during the loading and interaction stages of a webpage. It's an important feature for enhancing web performance by reducing file sizes and eliminating unnecessary code for faster page load times and a better user experience.</p>
<p>Removing unused JS and CSS code is a great way to save your users bandwidth. The Coverage tool allows you to find the unused code in your source code, and either remove it or defer it till the piece of code is needed.</p>
<p>On Chrome and Edge:</p>
<ul>
<li><p>In DevTools, press <code>Ctrl/cmd+Shift+P</code>, type coverage and select Start instrumenting coverage, refresh the page, then hit enter.</p>
</li>
<li><p>You’ll see a table of JS and CSS files with an unused byte column.</p>
</li>
<li><p>Click on any of the files to open it. The line by the side indicates which section of code isn’t unused in red.</p>
</li>
</ul>
<p>In the image below, we are identifying the unused CSS code to potentially remove or defer the loading of the code.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727898041299/ef5feb00-38db-4893-90db-275721c26399.png" alt="Delete unused code" width="1664" height="1430" loading="lazy"></p>
<p>From the image above, after the recording is complete, the Coverage tool will display a list of CSS and JavaScript files loaded by the page, along with detailed metrics:</p>
<ul>
<li><p>Total Bytes: The size of the file.</p>
</li>
<li><p>Unused Bytes: The number of bytes in the file that were not used.</p>
</li>
<li><p>Usage Visualization: A visual bar representing the proportion of used versus unused code.</p>
</li>
</ul>
<p>On Safari: In the Sources panel, open the left navigation sidebar and click on any JS file. At the top right of the toolbar, click on the coverage icon <code>c</code> and refresh your page. You'd be able to see that the sections of code not executed are grayed out.</p>
<h2 id="heading-how-to-enable-accessibility-tree-in-devtools">How to Enable Accessibility Tree in DevTools</h2>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Accessibility_tree">accessibility tree</a> is similar to the element DOM tree and is used by assistive technologies such as screen readers to read web content. Developers can use this feature to debug accessibility issues on their websites. Chromium browsers use <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/api/accessibilityFeatures">Chrome’s accessibility API</a> to make this possible, while Firefox has its own accessibility tool.</p>
<p>On Chrome and Edge:</p>
<ul>
<li><p>On the settings page, select the Experiments tab.</p>
</li>
<li><p>Check the box for the Enable full accessibility tree view option in the Elements panel.</p>
</li>
<li><p>Refresh DevTools and go to the Elements tool.</p>
</li>
<li><p>In the top-right corner of the element view, click Switch to DOM Tree view.</p>
</li>
</ul>
<p>For example, in the image below, we are checking if the links and buttons on our website are recognized correctly and accessible to users who rely on screen readers:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727898388525/1a73f242-5ccd-48ea-b167-440205285ba4.png" alt="Enable accessibility tree" width="2294" height="1430" loading="lazy"></p>
<p>With the accessibility tree enabled, you can see a simplified version of the DOM tree, focused on elements relevant for accessibility. When you select an element on the accessibility tree to view its properties, the tree displays the element’s role, name, and other important attributes, such as aria-label if they are present.</p>
<p>You’ll also see if the element is focusable and what its computed accessibility properties are.</p>
<p>This helps a great deal because if the element isn’t appearing correctly in the accessibility tree or is missing essential attributes, you may need to adjust your HTML or <a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/aria/">ARIA</a> attributes to improve accessibility.</p>
<p>On Firefox:</p>
<ul>
<li><p>In the Firefox DevTools, click on the accessibility tab and expand the document node.</p>
</li>
<li><p>You can click on different nodes to view their properties.</p>
</li>
<li><p>Accessibility issues for nodes will be displayed on the Checks tab.</p>
</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>In a nutshell, staying current with the latest cross-browser DevTools features will save you time as a web developer. This post touches on element inspection tips, some Console shortcuts to make your debugging process easier, and some useful tips for network monitoring.</p>
<p>Hopefully, you will keep exploring and using more DevTools features to improve your developer experience.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Cross-Browser Compatibility? How to Build Websites that Work Everywhere ]]>
                </title>
                <description>
                    <![CDATA[ When building for the web, it's easy to develop tunnel vision and only build for yourself. You may overlook the diverse needs of your audience and focus solely on your preferences and how things look on your preferred browser. This can cause you to m... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-cross-browser-compatibility/</link>
                <guid isPermaLink="false">66c5a34fdd1f1e4092a3256c</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Compatibility ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ophy Boamah ]]>
                </dc:creator>
                <pubDate>Wed, 06 Mar 2024 18:26:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/Cross-Browser.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When building for the web, it's easy to develop tunnel vision and only build for yourself. You may overlook the diverse needs of your audience and focus solely on your preferences and how things look on your preferred browser. This can cause you to miss out on crucial functionality aspects and lead to future compatibility issues on other browsers. </p>
<p>In this article, we'll dive into practical strategies for achieving cross-browser compatibility, focusing on specific UI components like form elements, scrollbars, and fonts. Then we'll discuss some general best practices that every web developer should adopt.</p>
<blockquote>
<p>“Remember that you are not your users — just because your site works on your MacBook Pro or high-end Galaxy Nexus, doesn't mean it will work for all your users!” – <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">MDN Web Docs</a></p>
</blockquote>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-cross-browser-compatibility">What is Cross-Browser Compatibility?</a></li>
<li><a class="post-section-overview" href="#heading-common-cross-browser-issues-and-solutions">Common Cross-Browser Issues and Solutions</a></li>
<li><a class="post-section-overview" href="#heading-best-practices-for-cross-browser-compatibility">Best Practices for Cross-Browser Compatibility</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-what-is-cross-browser-compatibility">What is Cross-Browser Compatibility?</h2>
<p>In simple terms, cross-browser compatibility is about ensuring that your website delivers a consistent, top-notch experience for all users, regardless of their browser choice. </p>
<p>Browsers use different engines, so by default they render websites differently. In order to get your websites to look and work the same regardless of the user's browser requires an understanding of unique browser capabilities.</p>
<p>Cross-browser compatibility says that ideally, a website should look and function the same whether someone is viewing it on Chrome, Microsoft Edge and Opera (powered by Blink engine), Firefox (powered by Gecko engine) or even Safari (powered by WebKit engine). </p>
<h3 id="heading-benefits-of-cross-browser-compatibility">Benefits of Cross-Browser Compatibility:</h3>
<ol>
<li>Wider reach – your websites are accessible to more users, regardless of the browser they use.</li>
<li>Consistent User Experience – your websites have a uniform look and functionality across platforms.</li>
<li>Better Search Engine Optimization (SEO) – your websites get higher rankings from being more user-friendly.</li>
</ol>
<h2 id="heading-common-cross-browser-issues-and-solutions">Common Cross-Browser Issues and Solutions</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/browserstack.png" alt="Image" width="600" height="400" loading="lazy">
<em>Infographic showing test results of a web page on different browsers. Image credit Browserstack</em></p>
<h3 id="heading-form-elements">Form Elements</h3>
<p>The appearance and behavior of form elements like <code>&lt;input&gt;</code>, <code>&lt;select&gt;</code>, <code>&lt;textarea&gt;</code>, and <code>&lt;button&gt;</code> can vary significantly across browsers. This affects both the visual aspect and usability of forms, including how users interact with them (for example, clicking, focusing, and typing).</p>
<p>For instance, placeholder text in <code>&lt;input&gt;</code> fields may appear fainter in one browser and more pronounced in another, leading to readability issues. </p>
<p>To resolve this:</p>
<ul>
<li>Use CSS to standardize the appearance of form elements as much as possible.</li>
<li>For placeholders, ensure contrast and legibility across browsers:</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-pseudo">::placeholder</span> { <span class="hljs-comment">/* Chrome, Firefox, Opera, Safari 10.1+ */</span>
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#909090</span>;
  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>; <span class="hljs-comment">/* Firefox */</span>
}

<span class="hljs-selector-tag">input</span><span class="hljs-selector-class">.studentid</span><span class="hljs-selector-pseudo">:-ms-input-placeholder</span> { <span class="hljs-comment">/* Microsoft Edge */</span>
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#909090</span>;
}
</code></pre>
<p>The CSS code above targets placeholder text in input fields across browsers, sets their color to #909090, and ensures full opacity for consistent visibility (with specific rules for Microsoft Edge).</p>
<h3 id="heading-fonts">Fonts</h3>
<p>Fonts and typography face several cross-browser compatibility issues, from varying default font sizes to differences in font rendering engines. This can affect the weight, spacing, and overall appearance of text.</p>
<p>A font might appear thinner and more spaced out in Chrome compared to Edge, affecting readability and design consistency. </p>
<p>To resolve this:</p>
<ul>
<li>Define a base font size in your CSS and use relative units (like <code>em</code> or <code>rem</code>) for text sizing as shown in the code below. This helps maintain scalability and consistency.</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">html</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>; <span class="hljs-comment">/* Define a base font size */</span>
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Open Sans'</span>, sans-serif;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.6</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#333</span>;
}

<span class="hljs-selector-tag">h1</span>, <span class="hljs-selector-tag">h2</span>, <span class="hljs-selector-tag">h3</span>, <span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">2rem</span>;;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1.5rem</span>;
}
</code></pre>
<ul>
<li>When using web fonts, ensure they are loaded properly across all browsers by using services like Google Fonts, which provide cross-browser compatible font loading:</li>
</ul>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"&lt;https://fonts.googleapis.com/css?family=Open+Sans&amp;display=swap&gt;"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
</code></pre>
<ul>
<li>The code below makes sure that the 'Open Sans' font looks the same on our website, no matter the browser. It does this first by using a version of the font that might already be on our computer to load things faster. Otherwise, it grabs it from the internet but swaps in a default font while waiting for the latter to load. </li>
</ul>
<pre><code class="lang-css"><span class="hljs-keyword">@font-face</span> {
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Open Sans'</span>;
  <span class="hljs-attribute">font-style</span>: normal;
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">400</span>;
  <span class="hljs-attribute">font-display</span>: swap;
  <span class="hljs-attribute">src</span>: <span class="hljs-built_in">local</span>(<span class="hljs-string">'Open Sans Regular'</span>), <span class="hljs-built_in">local</span>(<span class="hljs-string">'OpenSans-Regular'</span>), <span class="hljs-built_in">url</span>(&lt;https://fonts.gstatic.com/s/opensans/v15/mem8YaGs126MiZpBA-UFVZ0b.woff2&gt;) <span class="hljs-built_in">format</span>(<span class="hljs-string">'woff2'</span>);
}
</code></pre>
<h3 id="heading-scrollbars">Scrollbars</h3>
<p>Scrollbar styling has long been a challenge for web developers due to inconsistent support across different browsers. While browsers like Chrome, Safari, and Edge have provided ways to customize scrollbars using CSS, the level of support and ways of implementing them vary.</p>
<p>Recent updates have seen improvements in standardizing scrollbar customization, with most modern browsers adopting similar capabilities. But there are still some differences in the approach:</p>
<p>For <strong>Chrome, Edge, and Firefox</strong>, you can use the CSS <code>scrollbar-width</code> and <code>scrollbar-color</code> properties to customize the scrollbar's appearance. These are part of a newer standard aimed at providing a more consistent way of styling scrollbars across browsers that support it.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* For Chrome, Firefox, and Edge */</span>
<span class="hljs-selector-tag">scrollbar-width</span>: <span class="hljs-selector-tag">thin</span>;
<span class="hljs-selector-tag">scrollbar-color</span>: <span class="hljs-selector-id">#c0c0c0</span> <span class="hljs-selector-id">#f0f0f0</span>;
</code></pre>
<p><strong>For Safari</strong>, which uses the WebKit rendering engine, you'll need to use the <code>::-webkit-scrollbar</code> pseudo-element to achieve similar styling. This method is specific to WebKit-based browsers.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* For Safari */</span>
<span class="hljs-selector-class">.mostly-customized-scrollbar</span><span class="hljs-selector-pseudo">::-webkit-scrollbar</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#aaa</span>; <span class="hljs-comment">/* or add it to the track */</span>
}
</code></pre>
<p>The CSS code above customizes the appearance of scrollbars across those browsers by adjusting their size and colours.</p>
<p>But for consistency across all browsers, you'll need to design your web pages in a way that the default scrollbar appearance does not negatively impact your design.</p>
<h2 id="heading-best-practices-for-cross-browser-compatibility">Best Practices for Cross-Browser Compatibility</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/best-practices.jpeg" alt="Image" width="600" height="400" loading="lazy">
<em>Infographic showing measuring tools. Image credit Creative Bloq</em></p>
<h3 id="heading-define-a-doctype">Define a Doctype</h3>
<p>Start your HTML document with a <code>&lt;!DOCTYPE&gt;</code> declaration to ensure standards mode is activated. </p>
<p>This is important because it tells the web browser which version of HTML the page is written in. Without it, browsers might render the page in "quirks mode," – where the browser assumes you've written old, non-standard code. This ultimately leads to unpredictable styling and layout issues because modern web standards are not fully applied.</p>
<p>A <code>&lt;!DOCTYPE&gt;</code> declaration in HTML5 looks like this at the very beginning of your HTML file:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
</code></pre>
<h3 id="heading-use-a-css-reset">Use a CSS Reset</h3>
<p>A CSS reset is basically adding a set of rules that target common elements to remove their default styling, reducing browser-default discrepancies. </p>
<p>Various browsers have different inherent styles for HTML elements – margins, paddings, font sizes, and so on. So implementing a CSS reset makes sure that only the styles you write in your code will take effect. This leads to a consistent baseline for styling your webpage across various browsers. </p>
<p>There are developers that like to write theirs from scratch. And there are others like me, who use <a target="_blank" href="https://meyerweb.com/eric/tools/css/reset/">Eric Meyer's popular and free CSS reset</a> as you can see in the code below:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/</span>

<span class="hljs-selector-tag">html</span>, <span class="hljs-selector-tag">body</span>, <span class="hljs-selector-tag">div</span>, <span class="hljs-selector-tag">span</span>, <span class="hljs-selector-tag">applet</span>, <span class="hljs-selector-tag">object</span>, <span class="hljs-selector-tag">iframe</span>,
<span class="hljs-selector-tag">h1</span>, <span class="hljs-selector-tag">h2</span>, <span class="hljs-selector-tag">h3</span>, <span class="hljs-selector-tag">h4</span>, <span class="hljs-selector-tag">h5</span>, <span class="hljs-selector-tag">h6</span>, <span class="hljs-selector-tag">p</span>, <span class="hljs-selector-tag">blockquote</span>, <span class="hljs-selector-tag">pre</span>,
<span class="hljs-selector-tag">a</span>, <span class="hljs-selector-tag">abbr</span>, <span class="hljs-selector-tag">acronym</span>, <span class="hljs-selector-tag">address</span>, <span class="hljs-selector-tag">big</span>, <span class="hljs-selector-tag">cite</span>, <span class="hljs-selector-tag">code</span>,
<span class="hljs-selector-tag">del</span>, <span class="hljs-selector-tag">dfn</span>, <span class="hljs-selector-tag">em</span>, <span class="hljs-selector-tag">img</span>, <span class="hljs-selector-tag">ins</span>, <span class="hljs-selector-tag">kbd</span>, <span class="hljs-selector-tag">q</span>, <span class="hljs-selector-tag">s</span>, <span class="hljs-selector-tag">samp</span>,
<span class="hljs-selector-tag">small</span>, <span class="hljs-selector-tag">strike</span>, <span class="hljs-selector-tag">strong</span>, <span class="hljs-selector-tag">sub</span>, <span class="hljs-selector-tag">sup</span>, <span class="hljs-selector-tag">tt</span>, <span class="hljs-selector-tag">var</span>,
<span class="hljs-selector-tag">b</span>, <span class="hljs-selector-tag">u</span>, <span class="hljs-selector-tag">i</span>, <span class="hljs-selector-tag">center</span>,
<span class="hljs-selector-tag">dl</span>, <span class="hljs-selector-tag">dt</span>, <span class="hljs-selector-tag">dd</span>, <span class="hljs-selector-tag">ol</span>, <span class="hljs-selector-tag">ul</span>, <span class="hljs-selector-tag">li</span>,
<span class="hljs-selector-tag">fieldset</span>, <span class="hljs-selector-tag">form</span>, <span class="hljs-selector-tag">label</span>, <span class="hljs-selector-tag">legend</span>,
<span class="hljs-selector-tag">table</span>, <span class="hljs-selector-tag">caption</span>, <span class="hljs-selector-tag">tbody</span>, <span class="hljs-selector-tag">tfoot</span>, <span class="hljs-selector-tag">thead</span>, <span class="hljs-selector-tag">tr</span>, <span class="hljs-selector-tag">th</span>, <span class="hljs-selector-tag">td</span>,
<span class="hljs-selector-tag">article</span>, <span class="hljs-selector-tag">aside</span>, <span class="hljs-selector-tag">canvas</span>, <span class="hljs-selector-tag">details</span>, <span class="hljs-selector-tag">embed</span>, 
<span class="hljs-selector-tag">figure</span>, <span class="hljs-selector-tag">figcaption</span>, <span class="hljs-selector-tag">footer</span>, <span class="hljs-selector-tag">header</span>, <span class="hljs-selector-tag">hgroup</span>, 
<span class="hljs-selector-tag">menu</span>, <span class="hljs-selector-tag">nav</span>, <span class="hljs-selector-tag">output</span>, <span class="hljs-selector-tag">ruby</span>, <span class="hljs-selector-tag">section</span>, <span class="hljs-selector-tag">summary</span>,
<span class="hljs-selector-tag">time</span>, <span class="hljs-selector-tag">mark</span>, <span class="hljs-selector-tag">audio</span>, <span class="hljs-selector-tag">video</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">font</span>: inherit;
    <span class="hljs-attribute">vertical-align</span>: baseline;
}
<span class="hljs-comment">/* HTML5 display-role reset for older browsers */</span>
<span class="hljs-selector-tag">article</span>, <span class="hljs-selector-tag">aside</span>, <span class="hljs-selector-tag">details</span>, <span class="hljs-selector-tag">figcaption</span>, <span class="hljs-selector-tag">figure</span>, 
<span class="hljs-selector-tag">footer</span>, <span class="hljs-selector-tag">header</span>, <span class="hljs-selector-tag">hgroup</span>, <span class="hljs-selector-tag">menu</span>, <span class="hljs-selector-tag">nav</span>, <span class="hljs-selector-tag">section</span> {
    <span class="hljs-attribute">display</span>: block;
}
<span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1</span>;
}
<span class="hljs-selector-tag">ol</span>, <span class="hljs-selector-tag">ul</span> {
    <span class="hljs-attribute">list-style</span>: none;
}
<span class="hljs-selector-tag">blockquote</span>, <span class="hljs-selector-tag">q</span> {
    <span class="hljs-attribute">quotes</span>: none;
}
<span class="hljs-selector-tag">blockquote</span><span class="hljs-selector-pseudo">:before</span>, <span class="hljs-selector-tag">blockquote</span><span class="hljs-selector-pseudo">:after</span>,
<span class="hljs-selector-tag">q</span><span class="hljs-selector-pseudo">:before</span>, <span class="hljs-selector-tag">q</span><span class="hljs-selector-pseudo">:after</span> {
    <span class="hljs-attribute">content</span>: <span class="hljs-string">''</span>;
    <span class="hljs-attribute">content</span>: none;
}
<span class="hljs-selector-tag">table</span> {
    <span class="hljs-attribute">border-collapse</span>: collapse;
    <span class="hljs-attribute">border-spacing</span>: <span class="hljs-number">0</span>;
}
</code></pre>
<p>There's another group of developers that use <a target="_blank" href="https://necolas.github.io/normalize.css/">Normalize.css</a>, which you can install using a package manager like npm and then importing it in your CSS.</p>
<pre><code class="lang-bash">npm install normalize.css
</code></pre>
<h3 id="heading-review-css-property-support">Review CSS Property Support</h3>
<p>Before using advanced CSS features, check their compatibility on websites like <a target="_blank" href="https://caniuse.com/">Can I Use</a>. There, you can find detailed compatibility tables for HTML, CSS, and JavaScript features across different browsers and versions. This should help you make informed decisions about which technologies to use and when to implement fallbacks.</p>
<p>In the screenshot below, I searched for CSS Grid and immediately got to see the various browsers and their versions that support it. So before implementing CSS Grid on my web page, I have an idea of the browsers that it works with.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-05-at-9.06.17-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Browser compatibility for CSS Grid.</em></p>
<h3 id="heading-create-responsive-websites">Create Responsive Websites</h3>
<p>The multi-device world we currently live in demands that, as web developers, we make responsiveness a priority. </p>
<p>We can use fluid layouts, flexible images, and media queries to ensure our websites adapt to any screen size. The ripple effects of getting responsiveness right is cross-browser compatibility, accessibility and enhanced user experience.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/responsive-design-best-practices/">Here's an article</a> discussing some best practices for responsive design and how to implement them.</p>
<h3 id="heading-do-cross-browser-testing">Do Cross-Browser Testing</h3>
<p>Testing has become such a buzzword in programming lately, but this is because it's very important to make sure the code you write works as expected. </p>
<p>It's not just about checking if your TypeScript code runs smoothly, though. Even simpler web projects need thorough testing. </p>
<p>Cross-browser testing means trying your web pages on various browsers and devices to make sure they look and work consistently across board.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Cross-browser compatibility may be a mouthful to pronounce. But as we’ve seen, it's essential to consider when building websites. And you can gradually make your websites compatible by testing and tweaking your code and implementing some of the five best practices we’ve discussed above. </p>
<p>So, before you draw the curtains on your next website or web app, remember to check if your users on Chrome, Firefox, Safari, and other browsers are seeing and experiencing the same things.</p>
<p>Here are some helpful resources:</p>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">MDN Web Docs on Cross-browser compatibility</a></li>
<li><a target="_blank" href="https://medium.com/@codepaper_/the-significance-of-cross-browser-compatibility-in-website-development-8ea2cca480dc">Codepaper on Significance of Cross-browser compatibility</a></li>
<li><a target="_blank" href="https://meyerweb.com/eric/tools/css/reset/">Eric Meyer on CSS Reset</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cross-Browser Compatibility Testing – Best Practices for Web Developers ]]>
                </title>
                <description>
                    <![CDATA[ Imagine putting in a ton of work to build a web application. And then it works in the Chrome browser, but misbehaves in Mozilla, Safari, or any other browser. As a web developer, you're likely eager to create amazing web applications that reach users... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/cross-browser-compatibility-testing-best-practices-for-web-developers/</link>
                <guid isPermaLink="false">66d45e01264384a65d5a9508</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Compatibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Casmir Onyekani ]]>
                </dc:creator>
                <pubDate>Thu, 05 Oct 2023 23:40:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/10/cross-browser-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Imagine putting in a ton of work to build a web application. And then it works in the Chrome browser, but misbehaves in Mozilla, Safari, or any other browser.</p>
<p>As a web developer, you're likely eager to create amazing web applications that reach users across the globe. But one major challenge you'll face is ensuring that your web app works seamlessly on various web browsers. This is where cross-browser compatibility testing comes into play.</p>
<p>In this article, we'll dive into the challenges of cross-browser compatibility, and I'll give you some best practices to overcome them.</p>
<h2 id="heading-what-is-cross-browser-compatibility-testing">What is Cross-Browser compatibility testing?</h2>
<p>Cross-browser compatibility testing is a critical quality assurance process in web development. It involves testing and ensuring that a website or web application functions and appears consistently and correctly across different web browsers and their various versions.</p>
<p>Since web browsers are developed by different companies and have distinct rendering engines, they may interpret HTML, CSS, and JavaScript code differently. This can lead to discrepancies in how a website looks and behaves, causing issues for users who access the site using different browsers.</p>
<h2 id="heading-common-cross-browser-compatibility-issues">Common Cross-Browser Compatibility Issues</h2>
<p>One fundamental cross-browser compatibility concern relates to the rendering of web pages.</p>
<p>CSS styles add another layer of complexity. Inconsistencies in how browsers interpret and apply these styles can lead to visual disparities, such as variations in font sizes, colors, spacing, and layout. These discrepancies can undermine the website's design integrity and user experience.</p>
<p>Plugins like Flash or Java pose compatibility challenges, as not all browsers support them, and some browsers have disabled them entirely. This can result in certain features of a website not working as intended or being inaccessible to users on specific browsers.</p>
<p>Web developers often rely on third-party libraries and frameworks to streamline development. But these dependencies may not be universally compatible with all browsers.</p>
<p>Compatibility issues with these external tools can lead to malfunctions or performance bottlenecks, affecting the website's overall stability and functionality.</p>
<p>Browser-specific bugs related to form submission, caching, and other critical functions can create headaches for developers. These bugs may manifest differently on each browser, requiring meticulous testing and workarounds to ensure consistent performance and functionality across the board.</p>
<h2 id="heading-differences-between-cross-browser-and-compatibility-testing">Differences Between Cross-Browser and Compatibility Testing</h2>
<p>There are some key differences between cross-browser testing and compatibility testing. Here are the main ones:</p>
<h3 id="heading-scope">Scope</h3>
<p>Cross-browser testing focuses on ensuring that a website or web application functions consistently and correctly across different web browsers. It primarily addresses variations in rendering and behavior caused by different browsers' rendering engines.</p>
<p>Compatibility testing is a broader testing approach that encompasses not only different browsers but also various operating systems, devices, screen sizes, and network conditions. It assesses how well a website or application functions across a range of diverse environments.</p>
<h3 id="heading-objective">Objective</h3>
<p>The main objective of cross-browser testing is to verify that the website or web app looks, works, and behaves the same or very similarly across various browsers, such as Google Chrome, Mozilla Firefox, Apple Safari, Microsoft Edge, and others. It aims to eliminate visual discrepancies, functional issues, and inconsistencies in user experience.</p>
<p>The primary goal of compatibility testing is to ensure that the website or application is compatible with a wide array of user environments, such as browsers, operating systems (Windows, macOS, Android, iOS), devices (desktops, laptops, tablets, smartphones), and network conditions (internet speeds and connectivity types).</p>
<h3 id="heading-challenges">Challenges</h3>
<p>Challenges in cross-browser testing arise from variations in how browsers interpret HTML, CSS, and JavaScript code, as well as differences in supported features and standards compliance.</p>
<p>Challenges in compatibility testing include addressing issues related to device-specific features, operating system dependencies, and network-related performance problems in addition to cross-browser challenges.</p>
<p>In summary, cross-browser testing is a subset of compatibility testing. While cross-browser testing specifically focuses on ensuring consistent performance across different web browsers and versions, compatibility testing encompasses a wider range of factors, including browsers, operating systems, devices, and network conditions. This helps guarantee a seamless user experience across diverse user environments.</p>
<p>Both types of testing are crucial for delivering high-quality web applications that meet the needs of a broad user base.</p>
<h2 id="heading-importance-of-cross-browser-compatibility-testing">Importance of Cross-Browser Compatibility Testing</h2>
<p>Neglecting this crucial aspect of web development can result in missed opportunities and potential damage to your brand's reputation.</p>
<h3 id="heading-user-experience">User Experience</h3>
<p>Users access websites and web applications through a variety of browsers and devices. Ensuring compatibility across these platforms guarantees a consistent and seamless experience for all users.</p>
<p>Frustration resulting from a poorly rendered website on a specific browser can lead to a high bounce rate and loss of potential customers or visitors.</p>
<h3 id="heading-market-reach">Market Reach</h3>
<p>Different users prefer different web browsers. Ignoring compatibility testing means potentially alienating a significant portion of your audience.</p>
<p>By ensuring your website works well on popular browsers like Chrome, Firefox, Safari, and Edge, you maximize your market reach and accessibility.</p>
<h3 id="heading-maintaining-credibility">Maintaining Credibility</h3>
<p>A website that functions well across browsers reflects professionalism and attention to detail. On the contrary, a website with compatibility issues can harm your brand's credibility and reputation. Users might perceive your site as unreliable or poorly developed.</p>
<h3 id="heading-mobile-devices">Mobile Devices</h3>
<p>Mobile browsers come with their own set of quirks and challenges. Given the rise in mobile internet usage, ensuring compatibility with mobile browsers is crucial.</p>
<p>A website that adapts well to varying screen sizes and touch interfaces is essential for catering to the mobile audience.</p>
<h3 id="heading-seo-impact">SEO Impact</h3>
<p>Search engines like Google consider user experience as a ranking factor. If your website performs poorly on specific browsers, it might affect your search engine rankings. A lower search ranking can significantly reduce organic traffic to your site.</p>
<h3 id="heading-support-and-maintenance">Support and Maintenance</h3>
<p>A website that works smoothly across different browsers reduces the burden of ongoing support and maintenance. Fewer compatibility-related issues mean fewer updates and patches needed, saving time and resources in the long run.</p>
<h3 id="heading-accessibility-compliance">Accessibility Compliance</h3>
<p>Accessibility is not only a legal requirement in many regions but also a moral imperative. Ensuring compatibility with screen readers and other assistive technologies allow people with disabilities to access and use your website.</p>
<p>Failure to meet accessibility standards can lead to legal consequences and damage to your brand's reputation.</p>
<h3 id="heading-global-audience">Global Audience</h3>
<p>The internet connects people worldwide. International users will access your website using various browsers. Cross-browser compatibility ensures that language characters, fonts, and other regional aspects display correctly, enabling you to cater to a global audience effectively.</p>
<h3 id="heading-competitive-advantage">Competitive Advantage</h3>
<p>Websites that prioritize cross-browser compatibility gain a competitive edge. They can attract and retain users more effectively than those with compatibility issues.</p>
<p>A well-optimized site provides a better user experience, leading to higher user engagement and potentially higher conversion rates.</p>
<h2 id="heading-types-of-cross-browser-compatibility-testing">Types of Cross-Browser Compatibility Testing</h2>
<p>Here are some of the main types of cross-browser and compatibility testing:</p>
<h3 id="heading-functional-testing">Functional Testing</h3>
<p>This type of testing checks if all the interactive features and functionalities of a website work as expected across different browsers.</p>
<p>Examples are ensuring that forms can be submitted, buttons are clickable, navigation menus function correctly, and scripting interactions behave consistently.</p>
<h3 id="heading-visual-testing">Visual Testing</h3>
<p>This type of testing focuses on the visual appearance of a website or application across different browsers and devices.</p>
<p>Examples are verifying that fonts, colors, layouts, and images are displayed consistently, and that there are no visual glitches or misalignments.</p>
<h3 id="heading-performance-testing">Performance Testing</h3>
<p>This type of testing assesses how a website performs in terms of loading speed and responsiveness across various browsers and devices.</p>
<p>Examples are measuring page load times, checking the site's responsiveness on different screen sizes, and ensuring that resource-intensive features (videos or animations) do not cause performance issues.</p>
<h3 id="heading-cross-device-testing">Cross-Device Testing</h3>
<p>This type of testing ensures that a website functions properly on a range of devices, including desktops, laptops, tablets, and mobile phones.</p>
<p>Examples are testing touch interactions on mobile devices, verifying responsiveness on different screen resolutions, and confirming compatibility with various device orientations (landscape and portrait).</p>
<h3 id="heading-cross-platform-testing">Cross-Platform Testing</h3>
<p>This type of testing involves checking compatibility across different operating systems and browsers.</p>
<p>Example is to verify that the website functions consistently on both Windows and macOS computers, as well as Android and iOS devices.</p>
<h3 id="heading-browser-version-testing">Browser Version Testing</h3>
<p>This type of testing involves testing a website on different versions of a particular browser to ensure compatibility across various iterations.</p>
<p>An example is to test on older versions of popular browsers like Internet Explorer 11, or older versions of Firefox or Chrome, to support users who have not updated their browsers.</p>
<h3 id="heading-accessibility-testing">Accessibility Testing</h3>
<p>This type of testing helps ensure that a website is usable by people with disabilities and complies with accessibility standards such as WCAG (Web Content Accessibility Guidelines).</p>
<p>Examples are testing keyboard navigation, screen reader compatibility, and the use of ARIA (Accessible Rich Internet Applications) attributes to make the site more accessible to users with disabilities.</p>
<h3 id="heading-security-testing">Security Testing</h3>
<p>Security testing verifies that a website's security features and protocols work consistently across different browsers and platforms.</p>
<p>Examples are to ensure that SSL (Secure Sockets Layer) certificates are correctly implemented, that login forms are secure, and that security headers like Content Security Policy (CSP) are effective.</p>
<p>This comprehensive testing approach helps ensure a seamless and consistent user experience across diverse user environments.</p>
<h2 id="heading-roles-and-collaboration-in-cross-browser-compatibility-testing">Roles and Collaboration in Cross-Browser Compatibility Testing</h2>
<p>Cross-browser compatibility testing involves web developers, designers, and quality testers working together. Developers write clean code, designers ensure visual consistency, and testers find and document issues.</p>
<p>Collaboration is key. Developers and designers create flexible designs, and testers rely on their expertise. Communication is vital for resolving issues promptly and meeting compatibility standards.</p>
<p>External collaboration with users and clients is also crucial. User feedback helps identify real-world issues, and managing client expectations aligns with browser capabilities. Successful testing relies on technical know-how and a collaborative culture within the team and with external stakeholders.</p>
<h2 id="heading-best-practices-for-cross-browser-compatibility-testing">Best Practices for Cross-Browser Compatibility Testing</h2>
<p>By adhering to these best practices, web developers and testers can effectively tackle cross-browser compatibility challenges and deliver web experiences that are reliable and user-friendly across a wide range of browsers and devices.</p>
<ul>
<li><p>Identify Target Browsers: Determine which browsers are most commonly used by your target audience. Focus your testing efforts on these browsers to ensure the best user experience for the majority of your visitors.</p>
</li>
<li><p>Prioritize Popular Browsers: Give higher priority to testing on the most popular web browsers such as Google Chrome, Mozilla Firefox, Apple Safari, and Microsoft Edge. These browsers have larger user bases and are more likely to be used by your visitors.</p>
</li>
<li><p>Test on Mobile Devices: Don't forget to test on mobile browsers, including iOS Safari and Android Chrome, as mobile users make up a significant portion of internet traffic. Ensure that your website is responsive and mobile-friendly.</p>
</li>
<li><p>Use Browser Developer Tools: Familiarize yourself with the developer tools available in modern browsers. These tools allow you to inspect elements,<br>  debug JavaScript, and simulate different browser environments, making it easier to identify and fix issues.</p>
</li>
<li><p>Leverage Cross-Browser Testing Tools: Consider using cross-browser testing tools and services like BrowserStack, CrossBrowserTesting, or Sauce Labs.<br>  These platforms provide access to a wide range of browser and OS combinations, allowing you to test efficiently without setting up multiple physical environments.</p>
</li>
<li><p>Regularly Update Your Browser List: Keep your list of target browsers up to date. Browsers release new versions regularly, and older versions may become less relevant. Test on the latest browser versions to address potential issues before they become widespread.</p>
</li>
<li><p>Validate HTML and CSS: Use validation tools such as the <a target="_blank" href="https://validator.w3.org/">W3C Markup Validation Service</a> and <a target="_blank" href="https://www.cssportal.com/css-validator/">CSS Validator</a> to check your code for compliance with web standards. Valid code is more likely to render consistently across browsers.</p>
</li>
<li><p>Implement Graceful Degradation and Progressive Enhancement: Design your website with a "baseline" experience that works on all browsers and devices. Then, enhance the experience for modern browsers with additional features.<br>  This approach ensures that all users have a functional experience.</p>
</li>
<li><p>Perform Automated Testing: Consider setting up automated testing using tools like <a target="_blank" href="https://www.selenium.dev/">Selenium</a>, <a target="_blank" href="https://pptr.dev/">Puppeteer</a>, or <a target="_blank" href="https://testcafe.io/">TestCafe</a>. These tools allow you to create and run test scripts across various browsers automatically, saving time and ensuring consistency.</p>
</li>
<li><p>Regularly Review and Update: Stay informed about the latest developments in web standards, browser updates, and best practices. Periodically review and update your testing procedures to remain effective in ensuring cross-browser compatibility.</p>
</li>
<li><p>Test Accessibility: Ensure that your website complies with web accessibility standards, such as WCAG. Test with screen readers and other assistive technologies to make your site accessible to users with disabilities.</p>
</li>
<li><p>Document and Track Issues: Maintain a detailed log of cross-browser compatibility issues and their resolutions. This documentation will help your team address similar issues in the future and maintain a high level of consistency.</p>
</li>
</ul>
<h2 id="heading-tools-for-cross-browser-testing">Tools for Cross-Browser Testing</h2>
<p>You have access to various tools that can help you test your web projects efficiently. Let's look at a few popular ones now:</p>
<h3 id="heading-browserstack">BrowserStack</h3>
<p>This is a popular cloud-based cross-browser testing platform that allows you to test your website or web app on a wide range of browsers and operating systems.</p>
<p>It provides access to real browser instances for manual testing and supports automated testing with Selenium and Appium.</p>
<h3 id="heading-crossbrowsertesting">CrossBrowserTesting</h3>
<p>This is a cloud-based testing platform that offers a vast array of browsers and devices for cross-browser testing.</p>
<p>It provides live interactive testing as well as automated testing capabilities and integrates with various testing frameworks.</p>
<h3 id="heading-sauce-labs">Sauce Labs</h3>
<p>This is another cloud-based testing platform that offers a comprehensive range of browser and device combinations for testing web and mobile applications.</p>
<p>It supports both manual and automated testing and integrates with popular testing frameworks like Selenium and Appium.</p>
<h3 id="heading-lambdatest">LambdaTest</h3>
<p>This is a cloud-based cross-browser testing platform that provides access to a large selection of browsers and operating systems.</p>
<p>It offers live interactive testing and supports automated testing with popular testing frameworks.</p>
<h3 id="heading-browserling">Browserling</h3>
<p>This is a web-based tool that allows you to quickly test your website on a variety of browsers without the need for downloads or installations.</p>
<p>It offers real-time browser access and is suitable for quick checks and debugging.</p>
<h3 id="heading-browsershots">Browsershots</h3>
<p>This is an open-source tool that provides screenshots of your website or web app as it appears in different browsers and versions. While it doesn't offer live testing or interaction, it's useful for visual comparisons.</p>
<h3 id="heading-blisk">Blisk</h3>
<p>This is a browser specifically designed for web development and testing. It provides a side-by-side view of your website in multiple devices and browsers, making it easier to spot compatibility issues during development.</p>
<h3 id="heading-ghostlab">Ghostlab</h3>
<p>This is a paid tool for synchronized testing and debugging across multiple devices and browsers. It helps you inspect and debug issues in real time while maintaining synchronization between devices.</p>
<h3 id="heading-browser-devtools">Browser DevTools</h3>
<p>Most modern browsers, including Chrome, Firefox, Safari, and Edge, come with built-in developer tools. These tools are essential for inspecting, debugging, and testing websites directly in the browser environment. They offer features for emulating different browsers, devices, and network conditions.</p>
<p>These tools vary in terms of features, pricing, and ease of use, so it's essential to choose the one that best fits your specific cross-browser testing needs and budget.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Cross-browser compatibility testing is an essential aspect of web development. By following these best practices, you can ensure that your web applications provide a consistent and delightful user experience across different browsers.</p>
<p>A combination of cloud-based testing platforms and browser developer tools can provide comprehensive coverage for testing your web projects on different browsers and ensuring a consistent user experience.</p>
<p>Remember that the web development field is constantly changing, so continuous learning and adaptation are key to your success.</p>
<p>If you found this guide helpful and enjoyable, please give it a like. For more insightful tutorials, follow me on <a target="_blank" href="https://twitter.com/casweb_dev">X</a> for updates <strong>🙏</strong>.</p>
<p>Happy coding, and may your web apps thrive in every corner of the internet!</p>
<p>Kudos to ValueCoders for the cover image image.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Manage Browser Defaults with event.preventDefault() and event.stopPropagation() ]]>
                </title>
                <description>
                    <![CDATA[ By Dillion Megida Browsers have default interactions and behaviors for different events.  For example, when a user clicks a "submit" button on a form, the form is submitted to a URL by default.  When the child of an element is clicked, the click even... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/manage-default-behavior-in-browser/</link>
                <guid isPermaLink="false">66d84f414540581f645440fa</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 04 May 2022 19:59:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/pexels-startup-stock-photos-7359.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dillion Megida</p>
<p>Browsers have default interactions and behaviors for different events. </p>
<p>For example, when a user clicks a "submit" button on a form, the form is submitted to a URL by default. </p>
<p>When the child of an element is clicked, the click event also occurs on the element because it is the main container.</p>
<p>In some cases, you may want to override these defaults. In this article, we will learn what the <code>event.preventDefault()</code> and <code>event.stopPropagation()</code> methods are and how to use them to cancel some default actions that occur in the browser.</p>
<h2 id="heading-eventpreventdefault">event.preventDefault()</h2>
<p>This method prevents default actions that browsers make when an event is triggered. </p>
<p>Here are some examples of default actions on webpages and how to override them with <code>event.preventDefault()</code>.</p>
<h3 id="heading-how-to-override-default-form-submission">How to override default form submission</h3>
<p>When a user submits a form (the submit button clicked), the default action of the form is to submit the form's data to a URL that processes the data.</p>
<p>Form elements have the <code>action</code> and <code>method</code> attributes which specify the URL to submit the form to and the type of request (<code>get</code>, <code>post</code>, and so on), respectively. </p>
<p>If these attributes are not provided, the default URL is the current URL the form was submitted on, and the method is <code>get</code>.</p>
<p>For example, this code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>produces this page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/image-9.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On submitting the form with input "dillion" and "password", you can see a <code>get</code> request submitted to <code>127.0.0.1:5500/index.html</code> like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/image-10.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This action is how browsers handle forms by default. </p>
<p>But you may want to do more things to the data before sending a request. This is especially common in today's approach to handling forms. </p>
<p>You may want to do some data validation, data checks, processing, configuring headers, and so on before sending the request to a URL. </p>
<p>In these scenarios, you'll want to prevent the form's default action. Here's how:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'form'</span>&gt;</span>
  ...
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'form'</span>)

form.addEventListener(<span class="hljs-string">'submit'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.preventDefault()

  <span class="hljs-comment">// process data and submit a request manually</span>
})
</code></pre>
<p>This way, submitting the form is in your hands.</p>
<h3 id="heading-how-to-override-default-action-when-clicking-a-link">How to override default action when clicking a link</h3>
<p>When you click a link (an anchor tag <code>a</code> with a <code>href</code> attribute), the default action is a navigation on the browser to the clicked link.</p>
<p>What if you wanted to intercept that action and maybe do something before the navigation? For example, checking that the user has access to the page they want to navigate to. Here is how you'd do that:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"link"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://google.com"</span>&gt;</span>Google<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> link = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"link"</span>)

link.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  event.preventDefault()

  <span class="hljs-comment">// do something and navigate</span>
})
</code></pre>
<p>You can test it out. When you click the "Google" link, no navigation occurs – because you have prevented the default navigation action. Now, you have to handle the navigation yourself.</p>
<h2 id="heading-eventstoppropagation">event.stopPropagation()</h2>
<p>Propagation is the act of spreading something, in this case, events. The <code>stopPropagation</code> method is used to prevent the spreading of events when an event is triggered on an element.</p>
<p>In JavaScript, when you trigger an event on an element, it bubbles up the tree to the parents and ancestors of that element. Basically, the element with the event is "inside" the parent's container, so the parent also receives the events.</p>
<p>To explain this better, I'll use an example.</p>
<h3 id="heading-clicking-the-child-of-an-element">Clicking the child of an element</h3>
<p>Let's say you have the following elements:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>When you click on the <code>button</code>, you are also clicking on the <code>div</code> container because the button is in the container. This logic means that the click event propagates from the button to the container, and the event keeps spreading to all the grandparents until it gets to the root.</p>
<p>To verify this, I will explain how this works with this code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"div"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"button"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> div = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'div'</span>)
<span class="hljs-keyword">const</span> button = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'button'</span>)

button.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'button clicked'</span>)
})

div.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'div container clicked'</span>)
})
</code></pre>
<p>When you try to run this on your browser and you click the button, you will get this result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/image-4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The <code>div</code> container also receives the click event, so the click callback function is also called.</p>
<p>Event propagations are the default behaviour of events and elements, but in some cases, you may not want some behaviours. Amongst many examples, here is one.</p>
<p>Here is the Gmail New Message popup:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/image-6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>At the top, you have the three action buttons. One minimizes the popup, one makes the popup fullscreen, and one closes the popup.</p>
<p>But the top bar, with the "New Message" text, also has a click handler, so that when it's clicked, it minimizes the popup:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/image-8.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>One thing you want to avoid here is that, on clicking any of the buttons, you do not want the click event to propagate to the top bar and also execute the function for that event. What I mean is, on clicking the close button, for example, you do not want the top bar to also minimize. </p>
<p>In cases like this, you want to stop the propagation.</p>
<p>Let's say the popup is built like this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'top-bar'</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- The Message Element --&gt;</span>
  <span class="hljs-comment">&lt;!-- The Buttons --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> topBar = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'top-bar'</span>)
<span class="hljs-keyword">const</span> closeButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'close-btn'</span>)

topBar.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// minimize or maximize popup</span>
})

closeButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// close popup</span>
})
</code></pre>
<p>You will also want to add the <code>stopPropagation</code> method to the button's listener, to avoid spreading the event to the top bar. To do so, you will update the button's listener to:</p>
<pre><code class="lang-js">closeButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  event.stopPropagation()
  <span class="hljs-comment">// close popup</span>
})
</code></pre>
<p>With this in place, the top bar will only receive the click event when it is directly clicked on.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>The difference between <code>event.preventDefault()</code> and <code>event.stopPropagation()</code> is that the former prevents default actions made by the browser, while the latter prevents the default behaviors of events –propagating up the tree.</p>
<p>These default actions and behaviors are not mistakes, and you do not have to worry about them while you code. But there are scenarios where you want to override them, as we have seen in the examples in this article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write Your Own Browser Extension [Example Project Included] ]]>
                </title>
                <description>
                    <![CDATA[ In this article we will talk about Browser extensions – what they are, how they work, and how you can build your own. We will finish by actually writing our own extension (Super Fun!) which allows us to copy any code snippet to our clipboard with a c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/write-your-own-browser-extensions/</link>
                <guid isPermaLink="false">66baef94d453cb5eb795159f</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chrome extension ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abhilekh gautam ]]>
                </dc:creator>
                <pubDate>Tue, 02 Nov 2021 15:57:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/10/browsers.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article we will talk about Browser extensions – what they are, how they work, and how you can build your own.</p>
<p>We will finish by actually writing our own extension (Super Fun!) which allows us to copy any code snippet to our clipboard with a click of a single button.</p>
<p>To continue with this article:</p>
<ul>
<li><p>You need to have a basic understanding of JavaScript.</p>
</li>
<li><p>You need the Firefox browser (or any other browser will also work)</p>
</li>
</ul>
<h2 id="heading-what-is-a-browser-extension">What is a Browser Extension?</h2>
<p>A browser extension is something you add to your browser which enhances your browsing experience by extending the capacity of your browser.</p>
<p>As an example, think about an ad blocker which you might have installed on your device. This makes your browsing experience better by blocking ads when you surf the web.</p>
<h2 id="heading-how-to-write-your-own-basic-browser-extension">How to Write Your Own Basic Browser Extension</h2>
<p>Now let's start by writing a very basic extension.</p>
<p>To begin, we'll create a folder inside which we create a file named <code>manifest.json</code>.</p>
<h3 id="heading-what-is-a-manifest-file">What is a manifest file?</h3>
<p>A manifest file is a must have file in any browser extension. This file contains basic data about our extension like name, version, and so on.</p>
<p>Now inside the <code>manifest.json</code> file copy the following snippet:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"manifest_version"</span>:<span class="hljs-number">2</span>,
  <span class="hljs-attr">"version"</span>:<span class="hljs-string">"1.0"</span>,
  <span class="hljs-attr">"name"</span>:<span class="hljs-string">"Test"</span>,
}
</code></pre>
<p>[<strong>2025 Update</strong>: Chrome <a target="_blank" href="https://developer.chrome.com/docs/extensions/reference/manifest">currently only supports version 3</a> for manifest.json]</p>
<h3 id="heading-how-to-load-the-extension-file">How to load the extension file</h3>
<p>For Firefox users, follow these steps:</p>
<p>In the address bar, search for this:</p>
<pre><code class="lang-javascript">about:debugging#/runtime/<span class="hljs-built_in">this</span>-firefox
</code></pre>
<p>You will see an option to <em>Load Temporary Add-on</em>. Click on that option and choose the <code>manifest.json</code> file from the directory.</p>
<p>For Chrome users:</p>
<p>In the address bar search for this:</p>
<pre><code class="lang-javascript">chrome:<span class="hljs-comment">//extensions</span>
</code></pre>
<ul>
<li><p>Enable Developer Mode and switch into it.</p>
</li>
<li><p>Click the Load unpacked button and select the extension directory.</p>
</li>
</ul>
<p>Hurray! You've installed the extension successfully. But the extension doesn't do anything currently. Now let's add some functionality to our extension. To do this, we'll edit our <code>manifest.json</code> file like this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"manifest_version"</span>:<span class="hljs-number">2</span>,
  <span class="hljs-attr">"version"</span>:<span class="hljs-string">"1.0"</span>,
  <span class="hljs-attr">"name"</span>:<span class="hljs-string">"Test"</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">"main.js"</span>]
    }
  ]
}
</code></pre>
<p>In the above code, we added a content script to <code>manifest.json</code>. Content scripts can manipulate the Document Object Model of the web page. We can inject JS (and CSS) into a web page using a content script.</p>
<p><code>"matches"</code> contains the list of domains and subdomains where the content script should be added and <code>js</code> is an array of the JS files to be loaded.</p>
<p>Now inside the same directory create a <code>main.js</code> file and add the following code:</p>
<pre><code class="lang-js">alert(<span class="hljs-string">"The test extension is up and running"</span>)
</code></pre>
<p>Now reload the extension and when you visit any <code>URLs</code> you will see an alert message.</p>
<p><strong>Don't forget to reload the extension anytime you edit the code.</strong></p>
<h2 id="heading-how-to-customize-your-browser-extension">How to Customize Your Browser Extension</h2>
<p>Now let's have some more fun with our extension.</p>
<p>What we are going to do now is create a web extension that changes all the images of a webpage we visit to an image we choose.</p>
<p>For this, just add any image to the current directory and change the <code>main.js</code> file to:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"The extension is up and running"</span>);

<span class="hljs-keyword">var</span> images = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'img'</span>)

<span class="hljs-keyword">for</span> (elt <span class="hljs-keyword">of</span> images){
   elt.src = <span class="hljs-string">`<span class="hljs-subst">${browser.runtime.getURL(<span class="hljs-string">"pp.jpg"</span>)}</span>`</span>
   elt.alt = <span class="hljs-string">'an alt text'</span>
}
</code></pre>
<p>Let's see whats going on here:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> images = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">'img'</span>)
</code></pre>
<p>This line of code selects all the elements in the web page with the <code>img</code> tag .</p>
<p>Then we loop through the array images using a for loop where we change the <code>src</code> attribute of all the <code>img</code> elements to a URL with the help of the <code>runtime.getURL</code> function.</p>
<p>Here <code>pp.jpg</code> is the name of the image file in the current directory in my device.</p>
<p>We need to inform our content script about the <code>pp.jpg</code> file by editing the <code>manifest.json</code> file to:</p>
<pre><code class="lang-js">{
  <span class="hljs-string">"manifest_version"</span>:<span class="hljs-number">2</span>,
  <span class="hljs-string">"version"</span>:<span class="hljs-string">"1.0"</span>,
  <span class="hljs-string">"name"</span>:<span class="hljs-string">"Test"</span>,
  <span class="hljs-string">"content_scripts"</span>:[
   {
    <span class="hljs-string">"matches"</span>:[<span class="hljs-string">"&lt;all_urls&gt;"</span>],
    <span class="hljs-string">"js"</span>:[<span class="hljs-string">"main.js"</span>]
   }
  ],
  <span class="hljs-string">"web_accessible_resources"</span>: [
        <span class="hljs-string">"pp.jpg"</span>
  ]
}
</code></pre>
<p>Then just reload the extension and visit any URL you like. Now you should see all the images being changed to the image which is in your current working directory.</p>
<h3 id="heading-how-to-add-icons-to-your-extension">How to add icons to your extension</h3>
<p>Add the following code in the <code>manifest.json</code> file:</p>
<pre><code class="lang-json"><span class="hljs-string">"icons"</span>: {
  <span class="hljs-attr">"48"</span>: <span class="hljs-string">"icon-48.png"</span>,
  <span class="hljs-attr">"96"</span>: <span class="hljs-string">"icon-96.png"</span>
}
</code></pre>
<h3 id="heading-how-to-add-a-toolbar-button-to-your-extension">How to add a toolbar button to your extension</h3>
<p>Now we'll add a button located in the toolbar of your browser. Users can interact with the extension using this button.</p>
<p>To add a toolbar button, add the following lines to the <code>manifest.json</code> file:</p>
<pre><code class="lang-json"><span class="hljs-string">"browser_action"</span>:{
   <span class="hljs-attr">"default_icon"</span>:{
     <span class="hljs-attr">"19"</span>:<span class="hljs-string">"icon-19.png"</span>,
     <span class="hljs-attr">"38"</span>:<span class="hljs-string">"icon-38.png"</span>
   }
  }
</code></pre>
<p>All the image files should be present in your current directory.</p>
<p>Now, if we reload the extension we should see an icon for our extension in the toolbar of our browser.</p>
<h3 id="heading-how-to-add-listening-events-for-the-toolbar-button">How to add listening events for the toolbar button</h3>
<p>Maybe we want to do something when a user clicks the button – let's say we want to open a new tab every time the button is clicked.</p>
<p>For this, we'll again add the following to the <code>manifest.json</code> file:</p>
<pre><code class="lang-json"><span class="hljs-string">"background"</span>:{
        <span class="hljs-attr">"scripts"</span>:[<span class="hljs-string">"background.js"</span>]
  },
  <span class="hljs-string">"permissions"</span>:[
      <span class="hljs-string">"tabs"</span>
  ]
</code></pre>
<p>Then we'll create a new file named <code>background.js</code> in the current working directory and add the following lines in the file:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">openTab</span>(<span class="hljs-params"></span>)</span>{

    <span class="hljs-keyword">var</span> newTab = browser.tabs.create({
        <span class="hljs-attr">url</span>:<span class="hljs-string">'https://twitter.com/abhilekh_gautam'</span>,
        <span class="hljs-attr">active</span>:<span class="hljs-literal">true</span>
    })
}

browser.browserAction.onClicked.addListener(openTab)
</code></pre>
<p>Now reload the extension!</p>
<p>Whenever someone clicks the button, it calls the <code>openTab</code> function which opens a new tab with the URL that links to my twitter profile. Also, the active key, when set to true, makes the newly created tab the current tab.</p>
<p>Note that you can use APIs provided by browsers in the background script. For more about APIs refer to the following article: <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API">Javacript APIs</a>.</p>
<p>Now that we've learned some of the basics of browser extensions, let's create an extension that we as developers can use in our daily lives.</p>
<h2 id="heading-final-project">Final Project</h2>
<p>Alright, now we're going to write something that will be useful for us in daily life. We'll create an extension that allows you to copy code snippets from StackOverflow with a single click. So our extension will add a <code>Copy</code> button to the webpage which copies the code to our clipboard.</p>
<h3 id="heading-demo">Demo</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/demo.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>First we'll create a new folder/directory, inside which we'll add a <code>manifest.json</code> file.</p>
<p>Add the following code to the file:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"manifest_version"</span>:<span class="hljs-number">2</span>,
  <span class="hljs-attr">"version"</span>:<span class="hljs-string">"1.0"</span>,
  <span class="hljs-attr">"name"</span>:<span class="hljs-string">"copy code"</span>,
  <span class="hljs-attr">"content_scripts"</span>:[
    {
     <span class="hljs-attr">"matches"</span>:[<span class="hljs-string">"*://*.stackoverflow.com/*"</span>],
     <span class="hljs-attr">"js"</span>:[<span class="hljs-string">"main.js"</span>]
    }
  ]
}
</code></pre>
<p>Look at the <code>matches</code> inside the <code>content script</code> – the extension will only work for StackOverflow's domain and subdomain.</p>
<p>Now create another JavaScript file called <code>main.js</code> in the same directory and add the following lines of code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> arr =<span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">"s-code-block"</span>)

<span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span> ; i &lt; arr.length ; i++){
 <span class="hljs-keyword">var</span> btn = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"button"</span>)
 btn.classList.add(<span class="hljs-string">"copy_code_button"</span>)
 btn.appendChild(<span class="hljs-built_in">document</span>.createTextNode(<span class="hljs-string">"Copy"</span>))
 arr[i].appendChild(btn)
 <span class="hljs-comment">//styling the button</span>
 btn.style.position = <span class="hljs-string">"relative"</span>

 <span class="hljs-keyword">if</span>(arr[i].scrollWidth === arr[i].offsetWidth &amp;&amp; arr[i].scrollHeight === arr[i].offsetHeight)
  btn.style.left = <span class="hljs-string">`<span class="hljs-subst">${arr[i].offsetWidth - <span class="hljs-number">70</span>}</span>px`</span>

  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(arr[i].scrollWidth != arr[i].offsetWidth &amp;&amp; arr[i].scrollHeight === arr[i].offsetWidth)
   btn.style.left = <span class="hljs-string">`<span class="hljs-subst">${arr[i].offsetWidth - <span class="hljs-number">200</span>}</span>px`</span>
 <span class="hljs-keyword">else</span> 
   btn.style.left = <span class="hljs-string">`<span class="hljs-subst">${arr[i].offsetWidth - <span class="hljs-number">150</span>}</span>px`</span>

 <span class="hljs-keyword">if</span>(arr[i].scrollHeight === arr[i].offsetHeight)
   btn.style.bottom = <span class="hljs-string">`<span class="hljs-subst">${arr[i].offsetHeight - <span class="hljs-number">50</span>}</span>px`</span>

 <span class="hljs-keyword">else</span>
   btn.style.bottom = <span class="hljs-string">`<span class="hljs-subst">${arr[i].scrollHeight - <span class="hljs-number">50</span>}</span>px`</span>
 <span class="hljs-comment">//end of styling the button</span>

   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Appended"</span>)
}
</code></pre>
<p>First of all, I selected all the elements with the class name <code>s-code-block</code> – but why? This is because when I inspected StackOverflow's site I found that all the code snippets were kept in a class with that name.</p>
<p>And then we loop through all those elements and append a button in those elements. Finally, we just position and style the button properly (the styling's not perfect yet – this is just a start).</p>
<p>When we load the extension using the process we went through above and visit StackOverflow, we should see a copy button.</p>
<h3 id="heading-how-to-add-functionality-to-the-button">How to add functionality to the button</h3>
<p>Now, when the button is clicked we want the entire snippet to be copied to our clip board. To do this, add the following line of code to the <code>main.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> button = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".copy_code_button"</span>)
 button.forEach(<span class="hljs-function">(<span class="hljs-params">elm</span>)=&gt;</span>{
  elm.addEventListener(<span class="hljs-string">'click'</span>,<span class="hljs-function">(<span class="hljs-params">e</span>)=&gt;</span>{
    navigator.clipboard.writeText(elm.parentNode.childNodes[<span class="hljs-number">0</span>].innerText)
    alert(<span class="hljs-string">"Copied to Clipboard"</span>)
  })
 })
</code></pre>
<p>First of all, we select all the buttons we have added to the site using <code>querySelectorAll</code>. Then we listen for the click event whenever the button is clicked.</p>
<pre><code class="lang-js">navigator.clipboard.writeText(elm.parentNode.childNodes[<span class="hljs-number">0</span>].innerText)
</code></pre>
<p>The above line of code copies the code to our clipboard. Whenever a snippet is copied we alert the user with the message <code>Copied to clipboard</code> and we are done.</p>
<h2 id="heading-final-words">Final Words</h2>
<p>Web Extensions can be useful in various way and I hope with the help of this article you will be able to write your own extensions.</p>
<p>All the code can be found in <a target="_blank" href="https://github.com/Abhilekhgautam/Copy-Code">this GitHub</a> repository. Don't forget to give a pull request anytime you come up with some good styling or a new feature like clipboard history and others.</p>
<p><strong>Happy Coding!</strong></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Block Annoying Content From Web Pages Using uBlock Origin ]]>
                </title>
                <description>
                    <![CDATA[ You can use extensions in your browser to remove parts of a webpage you don't want to see. Removing annoyances, distractions, and irrelevant content is a great way to stay focused and remain efficient while you consume information on the internet. Th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-block-content-from-web-pages-using-ublock-origin/</link>
                <guid isPermaLink="false">66d460f0768263422736e8b1</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Seth Falco ]]>
                </dc:creator>
                <pubDate>Tue, 24 Aug 2021 19:39:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/untitled-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You can use extensions in your browser to remove parts of a webpage you don't want to see. Removing annoyances, distractions, and irrelevant content is a great way to stay focused and remain efficient while you consume information on the internet.</p>
<p>There are many extensions that add this functionality to your browser. I'll be focusing on <a target="_blank" href="https://ublockorigin.com/">uBlock Origin,</a> as many will already have it. If you don't, then I'd strongly recommend installing it.</p>
<h2 id="heading-what-is-ublock-origin">What is uBlock Origin?</h2>
<p><a target="_blank" href="https://ublockorigin.com/">uBlock Origin</a> is a free and open-source ad blocker available for all major browsers. It also includes an <a target="_blank" href="https://github.com/gorhill/uBlock/wiki/Element-picker">element picker</a> tool that can remove custom elements, which is what we'll be using in this article.</p>
<p>Having knowledge of CSS selectors or XPath will help you go through this tutorial, but isn't required. uBlock Origin provides visual tools to select elements without technical knowledge. Still, writing the selector manually will usually be more reliable.</p>
<h2 id="heading-why-blocking-elements-is-useful">Why Blocking Elements Is Useful</h2>
<p>On the internet, we're constantly consuming information, but quite often it's information that simply isn't relevant to us.</p>
<p>If you access particular websites frequently, it can be a big boost to productivity if you can conditionally single out the information you know you won't need and never consume it in the first place.</p>
<ul>
<li><p>Removing certain types of events from activity or social media feeds.</p>
</li>
<li><p>Removing popups that ask you to do things you don't want to.</p>
</li>
<li><p>Removing posts from particular authors on YouTube or social media.</p>
</li>
<li><p>Removing distractions or dynamic elements that draw your attention.</p>
</li>
</ul>
<h2 id="heading-how-to-filter-html-elements">How to Filter HTML Elements</h2>
<p>To filter elements, you can click the uBlock Origin icon at the top of your browser, then click the element picker, the one with the eye drop icon. (<a target="_blank" href="https://github.com/gorhill/uBlock/wiki/Element-picker">More Info</a>)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Untitled.png" alt="The uBlock Origin interface, it contains all actions that can be performed such as blocking media, fonts, or elements on the current page." width="600" height="400" loading="lazy"></p>
<p><em>The uBlock Origin interface, this appears if you click the icon in your browser's toolbar.</em></p>
<p>You can start by selecting the content you want to remove. Even if the selection isn't perfect, it's just a starting point.</p>
<p>Once the box appears at the bottom-right, you can use the visual tools with the "Pick" button and sliders, or manually specify a selector.</p>
<p>The content highlighted in red is what will be removed once you select the "Create" button. These changes will persist even after refreshing or revisiting the page at a later date. Let's see how this works.</p>
<h3 id="heading-css-selectors">CSS Selectors</h3>
<p>You can remove most elements you want to remove easily using CSS selectors. This is great for removing static content on the page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/image-93.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Removes all release and push events from appearing in my GitHub activity feed. (</em><code>##div.news div.release, div.news div.push</code>)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/image-85.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Removes the banner to download Slack. (</em><code>##.p-client__banners</code>)</p>
<h3 id="heading-xpath">XPath</h3>
<p>You'll usually want to use XPath for one of two reasons:</p>
<ul>
<li><p>You need to check against the value of an element.</p>
</li>
<li><p>You need to select an element based on the attributes of its children.</p>
</li>
</ul>
<p>This is useful for removing dynamic or user-generated content. We want to remove the entire element, but only if something inside it matches the criteria rather than the element itself.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/image-57.png" alt="Using the uBlock Origin cosmetic filter tool to highlight all elements that would be deleted from my current selection." width="600" height="400" loading="lazy"></p>
<p><em>Removes all plugins from DevilBro. (</em><code>##:xpath(//a[./div/div/p/object/a = "DevilBro"])</code>)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/image-58.png" alt="Using the uBlock Origin cosmetic filter tool to remove all elements I don't want to see. The site now displays as if they were never there." width="600" height="400" loading="lazy"></p>
<p><em>How it looks after removing all plugins by DevilBro.</em></p>
<h3 id="heading-troubleshooting-your-filters">Troubleshooting your filters</h3>
<p>When filtering elements, your selectors can break at any time. Websites change for various reasons, in most cases due to maintenance or updates.</p>
<p>Don't let that deter you from doing what you want, though. It just means you should keep this in mind when you remove elements.</p>
<p>Try to keep your selectors local to what you actually want to remove, but strict enough that it won't falsely select other elements on the page.</p>
<p>There are also many websites that don't appreciate client-side modifications, and try to hinder this by arbitrarily changing HTML attribute values or obfuscating them.</p>
<p>In these cases, it's best to specify <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors">CSS attribute selectors</a> or use XPath to partially match attribute values.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/image-91.png" alt="Selecting the &quot;Active Now&quot; view on Discord using a CSS attribute selector. The &quot;Active Now&quot; component is highlighed in red to indicate it will be removed." width="600" height="400" loading="lazy"></p>
<p><em>Removing the "Active Now" view on Discord using an attribute selector, (</em><code>##div[class^="nowPlayingColumn"]</code>)</p>
<h3 id="heading-how-to-remove-filters">How to Remove Filters</h3>
<p>If you no longer want to block something, or the website has changed, you can go to the settings to remove the old filter before making a new one.</p>
<p>To remove a custom filter:</p>
<ol>
<li><p>Navigate to the uBlock Origin settings.</p>
</li>
<li><p>Select the "My filters" tab.</p>
</li>
<li><p>Delete the lines with the filter(s) you want removed.</p>
</li>
<li><p>Click "Apply changes" at the top.</p>
</li>
<li><p>Refresh the page you were on.</p>
</li>
</ol>
<h2 id="heading-other-helpful-browser-extensions">Other Helpful Browser Extensions</h2>
<p>There are other extensions you can use to remove specific types of content on websites, too.</p>
<h3 id="heading-highlight-or-hide-search-engine-results">Highlight or Hide Search Engine Results</h3>
<p><a target="_blank" href="https://github.com/pistom/hohser">Highlight or Hide Search Engine Results</a> (HOHSER) supports all major search engines, including <a target="_blank" href="https://duckduckgo.com/">DuckDuckGo</a> and Google.</p>
<p>I believe domain blacklisting should be a native user-setting available in search engines, but until that's a thing, you can use this extension to hide results under domains you don't like.</p>
<ul>
<li><p>Websites with re-hosted or shady download links.</p>
</li>
<li><p>Search engine optimized junk, like fake coupon websites.</p>
</li>
<li><p>Websites that block users in the EU.</p>
</li>
</ul>
<h3 id="heading-i-still-dont-care-about-cookies">I still don't care about cookies</h3>
<p><a target="_blank" href="https://github.com/OhMyGuus/I-Still-Dont-Care-About-Cookies">I still don't care about cookies</a> removes cookie warnings from appearing on most websites, that way you don't have to deal with them yourself.</p>
<p>The extension will attempt to hide the cookie message, only accepting cookies if necessary.</p>
<p>I strongly recommend only using this in combination with extensions like uBlock Origin and Privacy Badger, to prevent undesirable cookies from being saved.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you're not in a situation where you feel the need to block a significant amount of content from the pages you load.</p>
<p>But if you do feel the need, I hope this makes browsing the internet just a little more bearable for you.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is about:blank? Chrome Blank Homepage Guide ]]>
                </title>
                <description>
                    <![CDATA[ You might have heard of about:blank but don't understand what it is. Or you've seen it appear when you first load up a fresh new session in the Chrome browser – just an empty white page with about:blank showing in your address bar. You might even see... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-about-blank-chrome-blank-homepage-guide/</link>
                <guid isPermaLink="false">66b1e4dd88a49cff617991e9</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dionysia Lemonaki ]]>
                </dc:creator>
                <pubDate>Wed, 21 Jul 2021 21:02:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/07/brandi-redd-aJTiW00qqtI-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You might have heard of about:blank but don't understand what it is. Or you've seen it appear when you first load up a fresh new session in the Chrome browser – just an empty white page with about:blank showing in your address bar.</p>
<p>You might even see it when you click a link to download something from the web or when clicking on a link to take you to another webpage.</p>
<p>Have you wondered why about:blank appears and what is it exactly? Let's find out.</p>
<h2 id="heading-should-you-worry-about-aboutblank">Should you worry about about:blank?</h2>
<p>So is about:blank just a blank page as the name suggests, or is there more to it than meets the eye?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-21-at-1.43.36-PM.png" alt="Screenshot-2021-07-21-at-1.43.36-PM" width="600" height="400" loading="lazy"></p>
<p>Does it have any benefits, or is it a useful feature? Should you keep it and use it, or should you get rid off it?</p>
<p>When about:blank shows up, it can be confusing for people and makes them worry. They see a blank page and think it's a virus – some dangerous malware – or that it means something has happened to their browser. They don't understand what it is and what is causing it.</p>
<p>This article answers the above questions. It covers why this page shows up in your browser URL field, why you may actually want to keep it, and if not, how to make it disappear and stop it from showing up.</p>
<h2 id="heading-why-does-your-browser-show-aboutblank">Why does your browser show about:blank?</h2>
<p>If you are seeing an empty page with about:blank as the address, you are indeed viewing an empty page that is built into Chrome. In fact, this is common in most modern web browsers like Mozilla Firefox, Apple Safari, Microsoft Edge, Internet Explorer and others.</p>
<p>This page is loaded by default when the browser has nothing else to display. </p>
<p>When a user hasn't specified a specific webpage to load when they first open up the browser, the browser itself does not know what to show So it chooses to show a special blank page that is built into it.</p>
<p>The browser always has to display something after all, even if that is blank.</p>
<h3 id="heading-is-aboutblank-a-virus">Is about:blank a virus?</h3>
<p>In and of itself about:blank is not malware. It is as innocent as it can be.</p>
<p>In general, you don't need to worry about it.</p>
<p>In some very rare cases about:blank can be a <em>symptom</em> of a virus.</p>
<p>It can indicate that your computer has detected something dangerous and is blocking viruses/malware when it comes across with a bad link/URL. </p>
<p>It can also appear after you have removed malware. After such a process, the browser won't know what action to perform.</p>
<p>In any case, if you are concerned that your computer has a virus, it is a good idea to investigate that and perform a scan with an antimalware program of your choice.</p>
<h2 id="heading-what-is-aboutblank">What is about:blank?</h2>
<p>As mentioned earlier, this is just a page built into your browser. </p>
<p>It's not a webpage, that is a page coming from the Internet. It's nothing more than a blank screen appearing in your browser.</p>
<p>Specifically, it's part of the "about" URI Scheme which is impelemented by a variety of different browsers. </p>
<p>The "about" URI Scheme is part of a naming convention that tells the browser to show its internal, built-in pages.</p>
<p>Besides about:blank, there is a long list of Chrome URLs, including some of the below:</p>
<ul>
<li>about:downloads to view Chrome's download list</li>
<li>about:bookmarks to view your saved bookmarks</li>
<li>about:accessibility shows accessibility information for each tab opened in the browser</li>
<li>about:apps to view the apps that come with the Chrome browser and those installed by the user</li>
</ul>
<p>If you type about:about you'll be able to go through them all:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-21-at-1.52.54-PM.png" alt="Screenshot-2021-07-21-at-1.52.54-PM" width="600" height="400" loading="lazy"></p>
<h2 id="heading-benefits-of-aboutblank">Benefits of about:blank</h2>
<p>This page is a favourite homepage choice for many users. It ensures their browser loads up with a white empty page when it opens for the first time.</p>
<p>It makes for a blazingly fast homepage as it starts the browser really quikcly. The browser doesn't lose time by making a request for a page across the Internet and waiting for the response.</p>
<p>So, this can help reduce your data usage if your internet connection is slow and you have limited badwidth. You are able to save computer and network resources.</p>
<p>A default blank page can also help you stay focused and not get distracted. You can just focus on searching for and visiting the page you want to view.</p>
<h2 id="heading-how-to-set-aboutblank-as-your-homepage">How to set about:blank as your homepage</h2>
<p>If you want to make about:blank your default start page, you'll need to configure your browser's settings.</p>
<p>Go to your settings menu and select "Settings":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-21-at-2.00.05-PM.png" alt="Screenshot-2021-07-21-at-2.00.05-PM" width="600" height="400" loading="lazy"></p>
<p>(you could have even typed about:settings!)</p>
<ul>
<li>In the search bar type "start-up".</li>
<li>Select "Open a specific page or set of pages". </li>
<li>Click "Add a new page" and type "about:blank"
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-21-at-2.06.29-PM.png" alt="Screenshot-2021-07-21-at-2.06.29-PM" width="600" height="400" loading="lazy"></li>
<li>Finally,press "Add"</li>
</ul>
<p>When you open a new tab you'll see an empty page.</p>
<h2 id="heading-how-to-stop-aboutblank-from-showing">How to stop about:blank from showing</h2>
<p>This page is not something you just "get rid off" as it is a feature built into your browser and it'll always be there, under the hood.</p>
<p>If your browser always opens up with a blank page and you don't like it, you can stop that from happening. It's probably set as a default home page and you need to change your settings.</p>
<p>Following the steps mentioned in the previous section, delete "about:blank" from the "Open a specific page or set of pages" option and select your favorite web page. Or you can select "Open the New Tab page" instead.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Overall, about:blank is a safe feature and shouldn't raise any concerns.</p>
<p>And if you don't like seeing it when you open your browser, you can just change it in your settings. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Chrome Bookmarks – How To Delete or Recover a Bookmark ]]>
                </title>
                <description>
                    <![CDATA[ Being able to save a web page you visit often is very useful. Perhaps you check the Google Analytics of your blog posts every day, or visit a recipe app for cooking inspiration. Whatever the reason, bookmarks in Chrome can save you time and hassle. J... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chrome-bookmarks-location-guide-how-to-delete-or-recover-a-bookmark/</link>
                <guid isPermaLink="false">66b1fa0b25ef0bb2c5a516cd</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abigail Rennemeyer ]]>
                </dc:creator>
                <pubDate>Tue, 23 Feb 2021 07:18:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/60270e0d0a2838549dcc4732.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Being able to save a web page you visit often is very useful. Perhaps you check the Google Analytics of your blog posts every day, or visit a recipe app for cooking inspiration.</p>
<p>Whatever the reason, bookmarks in Chrome can save you time and hassle. Just bookmark the page, and you can easily come back to it any time.</p>
<p>But what if you want to clean up your bookmarks? After all, you might no longer need that concert tickets website from several years ago. Well, that's easy enough to do, too.</p>
<p>In this article, you'll learn how to find your bookmarks in Chrome, and how to delete them, recover them, and otherwise manage them. Let's get started.</p>
<h2 id="heading-where-are-my-bookmarks-located-in-chrome">Where are my bookmarks located in Chrome?</h2>
<p>First, let's see where to find your bookmarks in the first place. There are a couple spots from which you can access them.</p>
<h3 id="heading-how-to-find-bookmarked-pages-under-the-bookmarks-tab-in-chrome">How to Find Bookmarked Pages under the Bookmarks Tab in Chrome</h3>
<p>First, there's the "Bookmarks" tab in your Chrome menu bar:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-3.30.48-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>The bookmark tab in Chrome is in the top menu bar.</em></p>
<p>If you click on that tab, it will bring up a dropdown menu which shows several options, like "Bookmark Manager" and "Bookmark this tab". It also lists any bookmarks or bookmark folders you currently have:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-3.32.12-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>For example, I have a "freeCodeCamp stuff" bookmark folder that contains many of my bookmarked pages and tabs.</em></p>
<p>If you click on a bookmark folder, it'll expand the list to show you all bookmarks in that folder, like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-3.39.30-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to display your current bookmarks in a bookmark folder</em></p>
<p>Any bookmarked pages that you don't have in a folder will simply be listed under the bookmarks tab in Chrome.</p>
<h3 id="heading-how-to-find-bookmarked-pages-under-settings-in-chrome">How to Find Bookmarked Pages under Settings in Chrome</h3>
<p>Your bookmarks are also located under your settings tab, the three vertical dots in the upper right corner of your browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.02.26-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to find your bookmarks in settings.</em></p>
<p>Just click those three dots and you'll see the right dropdown above. Hover over/click on "Bookmarks" and the left menu will pop out. There you'll see a similar bookmark menu with options like "Show Bookmarks Bar", "Bookmark Manager" and so on.</p>
<p>If you hover over, for example, a bookmark folder (the same folder we discussed above), you'll see all your bookmarks. Then you can just click on the one you want to visit.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.06.13-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Voilà - all your bookmarks.</em></p>
<h2 id="heading-how-to-add-a-bookmark-in-chrome">How to Add a Bookmark in Chrome</h2>
<p>There are a few ways to add bookmarks in Chrome. </p>
<ul>
<li>You can visit the bookmarks tab in the Chrome menu bar (that we discussed above) and select "Bookmark this Tab". A separate box will pop up with the name you want to give your bookmark (you can change this - just click into that highlighted box). Then click done.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.15.08-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to add a bookmark in Chrome.</em></p>
<ul>
<li>You can also visit the settings (three vertical dots), click on or hover over the "Bookmarks" tab, and then select "Bookmark this Tab". The same little box will pop up as above.</li>
<li>A third option is to simply click the little star icon in the address bar. That will bookmark the page you're currently on.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.31.42-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Click that star and it'll add a bookmark for you (after you click "Done").</em></p>
<p>But if you don't want to use your mouse and make that many clicks, there's another option.</p>
<h3 id="heading-how-to-add-or-manage-bookmarks-in-chrome-with-keyboard-shortcuts">How to Add or Manage Bookmarks in Chrome with Keyboard Shortcuts</h3>
<p>Sure enough, you can use keyboard shortcuts to add bookmarks and manage your bookmarks.</p>
<p>To bookmark a tab quickly, just key in Command+D / Ctrl+D (see below) - it'll bring up that same bookmark window as above. Then you can just hit enter if you don't want to update the bookmark's name or any other settings and it'll save it.</p>
<p>And to manage your bookmarks, just key in Option+Command+B / Ctrl+Shift+O (again, see below).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.10.43-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to add or manage bookmarks with keyboard shortcuts.</em></p>
<p>But we're getting a little ahead of ourselves. Now let's learn how to manage your bookmarks, and why you might want to do so.</p>
<h2 id="heading-how-to-manage-your-bookmarks-in-chrome">How to Manage your Bookmarks in Chrome</h2>
<p>Let's say you have a bunch of old bookmarks you don't need anymore. You may want to remove some of them so you aren't scrolling endlessly through a long (and partly irrelevant) list of bookmarks.</p>
<h3 id="heading-how-to-delete-a-bookmark-in-chrome">How to Delete a Bookmark in Chrome</h3>
<p>Well, it's easy to remove bookmarks you no longer need. Simply navigate to your bookmarks tab (through the Chrome menu bar or Settings - three dots - as we discussed above) and select "Manage Bookmarks". </p>
<p>Or you can use your handy keyboard shortcut (Option+Command+B / Ctrl+Shift+O) to bring up your bookmark manager. This is what you'll see (with your own bookmarks, of course):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.24.41-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to manage bookmarks in Chrome</em></p>
<p>If you have a bookmarks folder, like I do, just double-click to expand it and see all your bookmarks. It'll then list them all out like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.25.07-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You'll notice three vertical dots to the right of each bookmark. If you click on those, it'll bring up options to manage that bookmark:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.28.58-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Options for managing your bookmarks in Chrome.</em></p>
<p>You can edit and delete bookmarks, copy the page URL, open the bookmark in a new tab, and more.</p>
<p>If you select "Delete", that bookmark will disappear from your list. Be careful - there's no "Are you sure you want to delete this?" message. </p>
<p>But wait...what if you didn't mean to delete that bookmark you just deleted?</p>
<h2 id="heading-how-to-recover-a-deleted-bookmark-in-chrome">How to Recover a Deleted Bookmark in Chrome</h2>
<p>If you've just deleted a bookmark in Chrome and didn't mean to do so, it's ok. Just hit Command+Z / Ctrl+Z (the "undo" function/keyboard shortcut) and it'll bring it back.</p>
<p>But what if you've since closed Chrome or done other things? Command+Z / Ctrl+Z won't work. Fortunately, there's another way – it just requires a few more steps.</p>
<h3 id="heading-how-to-recover-a-bookmark-in-chrome-that-you-deleted-a-while-ago-on-macos">How to Recover a Bookmark in Chrome that you Deleted a While Ago on macOS</h3>
<p>First, go to Finder. In the window that pops up, find "Macintosh HD" in the left menu bar:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/Screen-Shot-2021-02-12-at-4.48.14-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to recover deleted bookmarks later or the next day.</em></p>
<p>Double click on the "Users" folder (and then you might have to select the user you want to use). Then double click on the following folders in this order (a new window with an alphabetized list will pop up each time you double-click): </p>
<ul>
<li>Library -&gt; Application Support -&gt; Google -&gt; Chrome -&gt; Default</li>
</ul>
<p>There, you'll find two files, one called "Bookmarks" and the other called "Bookmarks.bak". The .bak file contains your backed-up bookmarks, which will have those bookmarks that you accidentally deleted.</p>
<p>You're just a couple steps away from getting your deleted bookmarks back:</p>
<ul>
<li>Make a copy of the Bookmarks file and save it somewhere else (another location on your computer). You'll also need to rename it.</li>
<li>Now, back in Default, delete that original Bookmarks file. You need to get it out of there so you can use the .bak file as your new Bookmarks file instead.</li>
<li>Then you need to rename the .bak file to just "Bookmarks" (get rid of the .bak extension) so that it's now your Bookmarks file. This should get back any bookmarks you deleted.</li>
<li>Now you can close finder and Chrome. When you reopen Chrome, your bookmarks should be back!</li>
</ul>
<h3 id="heading-how-to-recover-a-bookmark-in-chrome-that-you-deleted-a-while-ago-on-windows">How to Recover a Bookmark in Chrome that you Deleted a While Ago on Windows</h3>
<p>Open a file browser and go to the directory where Google Chrome stores user data. This is usually in <code>C:\Users\&lt;username&gt;\AppData\Local\Google\Chrome\User Data\Default</code>.</p>
<p>Or if you use multiple Chrome people / profiles, your data might be in another directory like Profile 1. I'm recovering a bookmark I deleted on my work profile in Chrome, so my "Bookmarks" and "Bookmarks.bak" files are in <code>C:\Users\&lt;username&gt;\AppData\Local\Google\Chrome\User Data\Profile 1</code>.</p>
<p>Also, the AppData directory is hidden by default, and you may need to make hidden files and folders visible first.</p>
<p>To do that, open Windows File Explorer, click on the "View" tab, then click the box for "Hidden items" and make sure that's checked:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/windows-file-explorer-hidden-files.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the Default or Profile x directory, you'll find two files, one called "Bookmarks" and the other called "Bookmarks.bak". The .bak file contains your backed-up bookmarks, which will have those bookmarks that you accidentally deleted.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/windows-10-bookmarks-bookmarks-bak.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>The "Bookmarks" and "Bookmarks.bak" files on Windows 10</em></p>
<p>You're just a couple steps away from getting your deleted bookmarks back:</p>
<ul>
<li>Make a copy of the Bookmarks file and save it somewhere else (another location on your computer). You'll also need to rename it.</li>
<li>Now, back in Default or Profile x, delete that original Bookmarks file. You need to get it out of there so you can use the .bak file as your new Bookmarks file instead.</li>
<li>Then you need to rename the .bak file to just "Bookmarks" (get rid of the .bak extension) so that it's now your Bookmarks file. This should get back any bookmarks you deleted.</li>
<li>Now you can close your file browser and Chrome. When you reopen Chrome, your bookmarks should be back!</li>
</ul>
<h3 id="heading-how-to-recover-a-bookmark-in-chrome-that-you-deleted-a-while-ago-on-linux">How to Recover a Bookmark in Chrome that you Deleted a While Ago on Linux</h3>
<p>Open a file browser and go to the directory where Google Chrome stores user data. This is usually in <code>/home/&lt;username&gt;/.config/google-chrome/Default/</code>.</p>
<p>Note that .config is a hidden directory, and you may need to make hidden files and folders visible first. Also, the <code>google-chrome</code> directory may be in another location depending on your flavor of Linux and how you installed the browser.</p>
<p>In the Default directory, you'll find two files, one called "Bookmarks" and the other called "Bookmarks.bak". The .bak file contains your backed-up bookmarks, which will have those bookmarks that you accidentally deleted.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>The "Bookmarks" and "Bookmarks.bak" files on Linux Mint</em></p>
<p>You're just a couple steps away from getting your deleted bookmarks back:</p>
<ul>
<li>Make a copy of the Bookmarks file and save it somewhere else (another location on your computer). You'll also need to rename it.</li>
<li>Now, back in Default, delete that original Bookmarks file. You need to get it out of there so you can use the .bak file as your new Bookmarks file instead.</li>
<li>Then you need to rename the .bak file to just "Bookmarks" (get rid of the .bak extension) so that it's now your Bookmarks file. This should get back any bookmarks you deleted.</li>
<li>Now you can close your file browser and Chrome. When you reopen Chrome, your bookmarks should be back!</li>
</ul>
<p>And that's it! Now you know how to manage your bookmarks in Chrome on macOS, Windows, and Linux.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use HTML to Open a Link in a New Tab ]]>
                </title>
                <description>
                    <![CDATA[ Tabs are great, aren't they? They allow the multitasker in all of us to juggle a bunch of online tasks at the same time. Tabs are so common now that, when you click on a link, it's likely it'll open in a new tab. If you've ever wondered how to ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-html-to-open-link-in-new-tab/</link>
                <guid isPermaLink="false">66ac880ec5931c2d2889ae75</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kristofer Koishigawa ]]>
                </dc:creator>
                <pubDate>Tue, 08 Sep 2020 04:29:37 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c98dd740569d1a4ca1c7d.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Tabs are great, aren't they? They allow the multitasker in all of us to juggle a bunch of online tasks at the same time.</p>
<p>Tabs are so common now that, when you click on a link, it's likely it'll open in a new tab.</p>
<p>If you've ever wondered how to do that with your own links, you've come to the right place.</p>
<h2 id="heading-the-anchor-element">The Anchor Element</h2>
<p>To create a link on a web page, you need to wrap an anchor (<code>&lt;a&gt;</code>) element around text, then set its <code>href</code> attribute to the URL you want to link to.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Check out <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.freecodecamp.org/"</span>&gt;</span>freeCodeCamp<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p></p>
<p>Check out <a href="https://www.freecodecamp.org/">freeCodeCamp</a>.</p>

<p>If you click on the link above, the browser will open the link in the current window or tab. This is the default behavior in every browser.</p>
<p>To open a link in a new tab, we'll need to look at some of the other attributes of the anchor element's other attributes.</p>
<h2 id="heading-the-target-attribute">The Target Attribute</h2>
<p>This attribute tells the browser how to open the link.</p>
<p>To open a link in a new tab, just set the <code>target</code> attribute to <code>_blank</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Check out <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.freecodecamp.org/"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>&gt;</span>freeCodeCamp<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>Now when someone clicks on the link, it will open up in a new tab, or possibly a new window depending on the person's browser settings.</p>
<h2 id="heading-security-concerns-with-targetblank">Security concerns with <code>target="_blank"</code></h2>
<p>I strongly recommend that you always add <code>rel="noreferrer noopener"</code> to the anchor element whenever you use the <code>target</code> attribute:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Check out <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.freecodecamp.org/"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"noopener noreferrer"</span>&gt;</span>freeCodeCamp<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>This results in the following output:</p>
<p></p>
<p>Check out <a href="https://www.freecodecamp.org/" target="_blank">freeCodeCamp</a>.</p>

<p>The <code>rel</code> attribute sets the relationship between your page and the linked URL. Setting it to <code>noopener noreferrer</code> is to prevent a type of phishing known as <a target="_blank" href="https://en.wikipedia.org/wiki/Tabnabbing">tabnabbing</a>.</p>
<h2 id="heading-what-is-tabnabbing">What is tabnabbing?</h2>
<p>Tabnabbing, sometimes called reverse tabnabbing, is an exploit that uses the browser's default behavior with <code>target="_blank"</code> to gain partial access to your page through the <code>window.object</code> API.</p>
<p>With tabnabbing, a page that you link to could cause your page to redirect to a fake login page. This would be hard for most users to notice because the focus would be on the tab that just opened – not the original tab with your page.</p>
<p>Then when a person switches back to the tab with your page, they would see the fake login page instead and might enter their login details.</p>
<p>If you're interested in learning more about how tabnabbing works and what bad actors can do with the exploit, check out <a target="_blank" href="https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/">Alex Yumashev's article</a> and this one by <a target="_blank" href="https://owasp.org/www-community/attacks/Reverse_Tabnabbing">OWASP</a>. </p>
<p>If you'd like to see a <em>safe</em> working example, check out this <a target="_blank" href="https://mathiasbynens.github.io/rel-noopener/">page</a> and its <a target="_blank" href="https://github.com/mathiasbynens/rel-noopener">GitHub repo</a> for more information about the exploit and the <code>rel</code> attribute.</p>
<h2 id="heading-in-summary">In summary</h2>
<p>It's easy to use HTML to open a link in a new tab. You just need an anchor (<code>&lt;a&gt;</code>) element with three important attributes:</p>
<ol>
<li>The <code>href</code> attribute set to the URL of the page you want to link to,</li>
<li>The <code>target</code> attribute set to <code>_blank</code>, which tells the browser to open the link in a new tab/window, depending on the browser's settings, and</li>
<li>The <code>rel</code> attribute set to <code>noreferrer noopener</code> to prevent possible malicious attacks from the pages you link to.</li>
</ol>
<p>Again, here's a full working example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Check out <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.freecodecamp.org/"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"noopener noreferrer"</span>&gt;</span>freeCodeCamp<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<p>Which results in the following output in the browser:</p>
<p></p>
<p>Check out <a href="https://www.freecodecamp.org/" target="_blank">freeCodeCamp</a>.</p>

<p>Thanks again for reading. Happy coding.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Yesterday Tab – How to Reopen Closed Tabs in Chrome, Safari, and Firefox ]]>
                </title>
                <description>
                    <![CDATA[ It happens all the time – you accidentally close a tab you weren't really done with, or you want to visit a site you found yesterday. So what's the easiest way to reopen those closed tabs and get back to browsing? In this article, you'll learn how to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-reopen-closed-tabs-restore-pages-in-chrome-safari-and-firefox/</link>
                <guid isPermaLink="false">66b1fa47125aeccef6f65c47</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ how-to ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abigail Rennemeyer ]]>
                </dc:creator>
                <pubDate>Sun, 30 Aug 2020 17:47:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c98f8740569d1a4ca1d19.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>It happens all the time – you accidentally close a tab you weren't really done with, or you want to visit a site you found yesterday.</p>
<p>So what's the easiest way to reopen those closed tabs and get back to browsing?</p>
<p>In this article, you'll learn how to reopen closed tabs in Chrome, Safari, and Firefox so you don't ever have to panic if you close something by accident.</p>
<h2 id="heading-how-to-reopen-tabs-in-chrome">How to reopen tabs in Chrome</h2>
<h3 id="heading-the-keyboard-shortcut">The keyboard shortcut</h3>
<p>There are a couple ways to reopen tabs in Chrome. If you're into keyboard shortcuts, the easiest way is to simply hit Command+Shift+T (on Mac) or Ctrl+Shift+T (on Windows).</p>
<p>If you hit that combo once, it'll bring up the last tab you closed. Hit it again, and it'll bring up the one before that. And so on.</p>
<h3 id="heading-the-menu-options-way">The menu options way</h3>
<p>If you're a bigger fan of right-clicking, just right click on the tab menu bar area, and select "Reopen Closed Tab":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/reopen-closed-tab.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to reopen closed tabs in Chrome.</em></p>
<p>If you do that again, it'll open the tab you closed before that, and so on.</p>
<h3 id="heading-how-to-review-your-browser-history-in-chrome">How to review your browser history in Chrome</h3>
<p>What if you can't remember exactly when you opened that tab you're looking for? Or you can't remember exactly what the site was called?</p>
<p>In that case, you might just want to check out your browsing history – the list of the last x number of sites you've visited/tabs you closed over the past days or weeks.</p>
<p>To do this, open your Chrome browser and click on the three little dots or green arrow in the upper right corner.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/recently-closed-tabs-history.png" alt="Image" width="600" height="400" loading="lazy">
<em>Click on "History" to see your recently closed tabs.</em></p>
<p>That'll bring up the menu you see in the image above. The fourth option is "History" – hover or click on that and another menu will open to the left. This will list the tabs you've recently closed (the last 8-10 or so).</p>
<p>If you want to see your whole browsing history, you can click on the history tab at the top of the leftmost menu that popped up, like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/click-on-history.png" alt="Image" width="600" height="400" loading="lazy">
<em>Click on that second "History" tab to see your whole history.</em></p>
<p>And that will open up your browsing history, which will look something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/browser-history-total.png" alt="Image" width="600" height="400" loading="lazy">
<em>Your browser history - scroll down to see more.</em></p>
<p>You can see the scroll bar on the right - if you scroll down, it'll just keep loading more history. This lets you see where you've been on the internet. </p>
<p>Want to visit one of those sites? Just click on it and the browser will take you there (in the same window).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/click-on-site-browser-history.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And that's it!</p>
<h2 id="heading-how-to-reopen-tabs-in-safari">How to reopen tabs in Safari</h2>
<p>Similarly, in Safari there are a couple ways to reopen tabs you've closed.</p>
<h3 id="heading-the-keyboard-shortcut-1">The keyboard shortcut</h3>
<p>The same keyboard shortcut we talked about for Chrome, above, works in Safari as well.</p>
<p>Just hit Command+Shift+T (Mac) or Ctrl+Shift+T (Windows) to open those tabs back up. Remember, you can do this multiple times to keep getting more closed tabs, in the order you closed them (from most-least recent).</p>
<h3 id="heading-the-menu-options-way-1">The menu options way</h3>
<p>Again, if you prefer using your mouse and menu bar, here's how it works in Safari:</p>
<p>In the menu bar at the top of your screen (where it has options like "Safari, File, Edit, View, History" and so on), select "History":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/recently-closed-tabs-safari.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to view your recently closed tabs in Safari.</em></p>
<p>This will bring up a few options, as you can see above. I've hovered over "Recently Closed" (the first option) and it shows me my two recently closed tabs. If you use Safari as your browser you will likely see more tabs.</p>
<p>If you see the tab you just closed that you want to open back up, just click on it and it will open in a new tab/window.</p>
<p>You also have the option to "Reopen Last Closed Tab" (which also lists the keyboard shortcut next to it) and "Restore All Windows from Last Session".</p>
<h3 id="heading-how-to-review-your-browser-history-in-safari">How to review your browser history in Safari</h3>
<p>If you want to review your whole browser history, just click on that first option under the "History" menu (that says "Show All History", see image above), and your entire history will appear:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/safari-whole-history.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Again, if you use Safari for your regular browser, your history will likely be longer :)</p>
<p>If you want to visit one of those sites directly, just double click on the listed URL and it'll take you there in that same window.</p>
<h2 id="heading-how-to-reopen-tabs-in-firefox">How to reopen tabs in Firefox</h2>
<p>If you're a Firefox user, the process is fairly similar to what we discussed above.</p>
<h3 id="heading-the-keyboard-shortcut-2">The keyboard shortcut</h3>
<p>You can open your recently closed tab(s) in Firefox the same way as in Chrome or Safari – with the Command+Shift+t (Mac) or Ctrl+Shift+t (Windows) keyboard shortcut. Easy peasy.</p>
<p>And if you hit those keys again and again, it'll keep opening the tabs you closed in order from most recently closed to least recently closed.</p>
<h3 id="heading-the-menu-options-way-2">The menu options way</h3>
<p>To open your recently closed tabs in Firefox via menu options, just find the icon in the upper right corner that looks like books on a shelf:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/Firefox-history-tab.png" alt="Image" width="600" height="400" loading="lazy">
<em>Step 1 - find the "History" tab.</em></p>
<p>When you click that, you'll get a dropdown menu that will have a "History" tab. Click on that, as highlighted in the image above.</p>
<p>This will bring up a new menu which will have a "Recently Closed Tabs" option, like you can see below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/open-recently-closed-tabs-firefox.png" alt="Image" width="600" height="400" loading="lazy">
<em>Step 2 - find your recently closed tabs in Firefox.</em></p>
<p>If you click on that, another menu will open with all your recently closed tabs listed.</p>
<p>If you click on one of those tabs shown, Firefox will take you to that tab in a new window.</p>
<h3 id="heading-how-to-view-your-browser-history-in-firefox">How to view your browser history in Firefox</h3>
<p>Of course if you want to see all the browsing you've done, not just tabs you've recently closed, you can view your whole browser history.</p>
<p>Under that same little books-on-a-shelf looking icon in the upper right, again click on the "History" option. Then you'll see your recent history, as well as an option to see all history:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/Show-all-history-firefox.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to see recent history or show all history in Firefox.</em></p>
<p>If you need more than just your recent history (shown there in the dropdown menu) you can click on "Show All History" at the bottom and it'll open up a separate window like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/firefox-whole-history.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to see all your history on Firefox.</em></p>
<p>If you want to visit any of those pages, just double click on the URL/line and Firefox will take you there in the same window.</p>
<h2 id="heading-thats-it">That's it!</h2>
<p>Now you can confidently reopen tabs in your browser so you don't lose track of what you were working on or learning.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Visual Studio Code Live Server Not Working ]]>
                </title>
                <description>
                    <![CDATA[ VSCode has a lot of great extensions, and Live Server is one of the best.  With just a couple of clicks, Live Server lets you see your page live in an actual browser. Better yet, it features live reloading, so if you update your code, the changes are... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/visual-studio-code-live-server-not-working/</link>
                <guid isPermaLink="false">66c3648f0002df282f2225af</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Visual Studio Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Visual Studio Code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 14 Aug 2020 09:28:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9941740569d1a4ca1eab.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>VSCode has a lot of great extensions, and <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">Live Server</a> is one of the best. </p>
<p>With just a couple of clicks, Live Server lets you see your page live in an actual browser. Better yet, it features live reloading, so if you update your code, the changes are also reflected in the browser.</p>
<p>All you have to do is right click in the HTML file you want to view, right click, then select "Open with Live Server":</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/live-server-ex.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Live Server in action</em></p>
<p>But what if Live Server doesn't open your browser and show your page like you expect? If this is happening to you, here are a few things you can try.</p>
<h2 id="heading-restart-vscode">Restart VSCode</h2>
<p>Sometimes the best you can do is start VSCode from scratch.</p>
<p>First, save all of your work. Then close VSCode, which will also stop all of the extensions you've installed.</p>
<p>Then, reopen VSCode and try again – go to the HTML file you want to view, right click, and select "Open with Live Server".</p>
<h2 id="heading-set-the-browser-for-live-server">Set the browser for Live Server</h2>
<p>It's possible that the extension is working, but your system doesn't have a default browser.</p>
<p>Even if you did set the default browser for your system, it wouldn't hurt to let Live Server know which browser you'd like to use explicitly.</p>
<p>First, open the Command Pallete with F1, then type in <code>Preferences: Open Settings (JSON)</code> and select that option.</p>
<p>This will open your VSCode <code>settings.json</code> file.</p>
<p>Scroll all the way to the bottom of the file, add a comma after the last setting, then paste in <code>"liveServer.settings.CustomBrowser": "chrome"</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/settings-json.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Note that you can also use <code>"firefox"</code>, <code>"safari"</code>, or any other browser as the value for the <code>"liveServer.settings.CustomBrowser"</code> setting.</p>
<p>Finally, save the <code>settings.json</code> file and try to run Live Server again.</p>
<h2 id="heading-set-the-default-browser-for-your-operating-system">Set the default browser for your operating system</h2>
<p>Even after telling Live Server which browser you want to use, it's possible that it's still not opening your page in that browser correctly.</p>
<p>The next thing to try is to set the default browser for your operating system itself.</p>
<p>The exact method for doing this can vary based on your operating system, so it's best to search for how to do this if you aren't sure.</p>
<p>Here's what the settings page looks like in Windows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/image-56.png" alt="Image" width="600" height="400" loading="lazy">
<em>Credit: <a target="_blank" href="https://forum.freecodecamp.org/u/Advitya-sharma">Advitya-sharma</a></em></p>
<h2 id="heading-go-to-the-live-page-yourself">Go to the live page yourself</h2>
<p>If for some reason Live Server still isn't opening the page in your browser automatically, no worries. You can always open the browser of your choice and view the page directly.</p>
<p>Just open your preferred browser and go to <code>http://127.0.0.1:5500/&lt;your_file_name&gt;</code>.</p>
<p>For example, if your file is called <code>index.html</code>, just go to <code>http://127.0.0.1:5500/index.html</code>.</p>
<p>As long as Live Server is running, you should see your page.</p>
<h2 id="heading-in-closing">In closing</h2>
<p>Those are a few common fixes you can try if Live Server isn't working the way you expect.</p>
<p>Stay safe, and happy (live) coding.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ About Blank – What Does about:blank Mean and Should You Get Rid of It? ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever tried to go to a web page and instead see "about:blank" displayed in the address bar where your hoped-for URL should be? Don't worry – it happens sometimes, and it isn't anything bad. In this article, you'll learn: what about:blank mea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/about-blank-what-does-about-blank-mean-and-why-is-it-blocked-in-chrome-and-firefox/</link>
                <guid isPermaLink="false">66b1fa069a6b87531e8fe7ca</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ internet ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abigail Rennemeyer ]]>
                </dc:creator>
                <pubDate>Sun, 28 Jun 2020 22:55:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/06/5f9c9a01740569d1a4ca22f9.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever tried to go to a web page and instead see "about:blank" displayed in the address bar where your hoped-for URL should be?</p>
<p>Don't worry – it happens sometimes, and it isn't anything bad. In this article, you'll learn:</p>
<ul>
<li>what about:blank means</li>
<li>what causes it to appear</li>
<li>why you might want to use it</li>
<li>whether you can get rid of it, and</li>
<li>whether you need to worry about it </li>
</ul>
<p>So let's dive in.</p>
<h2 id="heading-what-is-aboutblank">What is about:blank?</h2>
<p>About:blank is a page that appears when your browser has nothing else to display. It's not a page on the internet, but rather something internally inside your browser.</p>
<p>The "about" part of what you see comes from your browser's <a target="_blank" href="https://en.wikipedia.org/wiki/About_URI_scheme#:~:text=about%20is%20an%20internal%20URI,registered%20scheme%2C%20and%20is%20standardized.&amp;text=An%20exception%20is%20about%3Ablank%20%2C%20which%20is%20not%20translated.">about URI or URL scheme</a>. You can type "about:[whatever]" in the address bar to learn more information about your browser.</p>
<p>This works in most major browsers like Chrome, Firefox, Safari, Edge, Chromium, Internet Explorer, and so on.</p>
<p>For example, in Chrome you can type "about:dino" (which Chrome changes to chrome://dino) and you'll get Chrome's infamous "No Internet" dino message:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/about-dino.png" alt="Image" width="600" height="400" loading="lazy">
<em>Wait, but why?</em></p>
<p>If you've never played the no-internet dinosaur game, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-play-the-no-internet-google-chrome-dinosaur-game-both-online-and-offline/">learn how here</a> (and be prepared to waste hours of your life). But that's neither here nor there.</p>
<p>More usefully, for example, "about:about" displays a list of Chrome URLs:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/about-about-chrome.png" alt="Image" width="600" height="400" loading="lazy">
<em>So many URLs (and there were more. Screenshots can only be so big.)</em></p>
<p>Now back to the ":blank" part of about:blank. It just tells your browser to throw up that blank page when it doesn't have something else to display.</p>
<p>So it literally just shows you a plain white page with nothing on it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/about-blank.png" alt="Image" width="600" height="400" loading="lazy">
<em>They named it well.</em></p>
<p>Now again, this isn't some location on the interwebs - it's a blank page your browser keeps on hand for just such a purpose.</p>
<h2 id="heading-what-causes-aboutblank">What causes about:blank?</h2>
<p>So why does this blank page sometimes appear? Some of the main reasons are:</p>
<ul>
<li>If you've come across a bad link/URL</li>
<li>If the browser doesn't know where to go or what to do, it has to do <strong>something</strong> – so it shows you about:blank</li>
<li>If your browser detects something dangerous (like malware), certain browsers will display about:blank instead of proceeding into dangerous territory.</li>
</ul>
<p>So as you can see, about:blank in and of itself isn't really anything to worry about. But if you're seeing it a lot, you might want to check your computer for malware. More on that below.</p>
<h2 id="heading-uses-for-aboutblank">Uses for about:blank</h2>
<p>Now you might be wondering – why would I want this blank page to appear on purpose? Seems pretty useless.</p>
<p>Not so fast.</p>
<p>If you have limited bandwidth/a slow internet connection, you can set your browser's homepage to be about:blank. This way, whenever you open your browser or a new tab, it'll load super quickly without wasting a single resource or millisecond.</p>
<h3 id="heading-how-to-set-aboutblank-as-your-homepage">How to set about:blank as your homepage</h3>
<p>In Chrome, open the menu (those three little vertical dots in the upper right corner of the browser) and scroll down to the "On Startup" section (likely at the bottom):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/make-about-blank-homepage-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Then select "Open a specific page or set of pages" (the third option) and type in "about:blank" to the text field that appears. </p>
<p>Then when you open your browser or a new tab, you should see a blank white page.</p>
<h3 id="heading-other-uses-for-aboutblank">Other uses for about:blank</h3>
<p>You might also want to make sure that, when you open up your browser, no tabs or anything from your previous browsing session were preserved. </p>
<p>This is helpful from a privacy perspective, and also allows you to start a browsing session without internet, which uses less bandwidth.</p>
<h2 id="heading-can-you-get-rid-of-aboutblank">Can you get rid of about:blank?</h2>
<p>About:blank isn't really something you "get rid of" or avoid. But if you're seeing it every time you open your browser, it could be that it's set to display about:blank upon launch.</p>
<p>If you don't want that to happen, simply go in and change your homepage to whatever you want it to be (following the same steps as above).</p>
<h2 id="heading-is-aboutblank-malware-or-a-virus">Is about:blank malware or a virus?</h2>
<p>As we've seen throughout this article, about:blank itself isn't anything malicious. But it could be a sign that your computer is blocking malware. So they can be related.</p>
<p>Some anti-virus and anti-malware software use about:blank when they detect a bad URL or site. So instead of directing you to that malicious site, the browser throws up that blank page to protect you.</p>
<p>The about:blank page can also appear after you've removed malware from your system. If, in the process of removal, something broke, the browser will display about:blank because it can't complete the action you asked it to perform.</p>
<p>In the end, unless you want to set about:blank as your homepage or think you need to investigate possible malware or viruses on your machine, you don't need to worry about about:blank.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Debug JavaScript with your Browser's Devtools ]]>
                </title>
                <description>
                    <![CDATA[ As a developer you will often want to debug code. You might have already used console.log in some of the challenges, which is the simplest way to debug. In this article we will tell you some of the coolest tricks, to debug using the native debug-tool... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-debug-javascript-with-your-browsers-devtools/</link>
                <guid isPermaLink="false">66c35161a7aea9fc97bdfb93</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ debugging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 07 Feb 2020 22:14:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9cb5740569d1a4ca33be.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a developer you will often want to debug code. You might have already used <code>console.log</code> in some of the challenges, which is the simplest way to debug.</p>
<p>In this article we will tell you some of the coolest tricks, to debug using the native debug-tools of the browsers.</p>
<h2 id="heading-a-brief-insight-into-the-freecodecamp-code-editor"><strong>A brief insight into the FreeCodeCamp Code Editor:</strong></h2>
<p>Before jumping into debugging lets leak out some secret facts about that <em>awesome code checking engine</em> at FCC.</p>
<p>We use a customized <a target="_blank" href="http://codemirror.net/mode/javascript/index.html">CodeMirror</a>, as the code editor. A <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval"><code>eval()</code> function</a> is used to evaluate the JavaScript code represented as a string from the editor. When <code>eval()</code> is called, browsers will natively execute your code. We will learn more why this secret is important in later sections of this article.</p>
<h2 id="heading-now-moving-on-to-the-tricks"><strong>Now moving on to the tricks:</strong></h2>
<h2 id="heading-google-chrome-devtools"><strong>Google Chrome DevTools</strong></h2>
<p>Google Chrome is one of the most popular browsers with a built-in JavaScript engine called <a target="_blank" href="https://developers.google.com/v8/">V8</a>, and offers a great toolset for developers called <a target="_blank" href="https://developer.chrome.com/devtools">Chrome DevTools</a>. Visiting their <a target="_blank" href="https://developer.chrome.com/devtools/docs/javascript-debugging">Complete JavaScript debugging guide</a> is highly recommended.</p>
<h3 id="heading-1-basics-of-devtools"><strong>1 : Basics of DevTools</strong></h3>
<h4 id="heading-launching-the-chrome-devtools"><strong>Launching the Chrome DevTools</strong></h4>
<p>Hit <code>F12</code></p>
<p>. Alternatively you can press</p>
<p><code>Ctrl</code> + <code>Shift</code> + <code>I</code></p>
<p>on Windows and Linux or</p>
<p><code>Cmd</code> + <code>Shift</code> + <code>I</code></p>
<p>on Mac, or If you just love your mouse go to <code>Menu &gt; More Tools &gt; Developer Tools</code>.</p>
<h4 id="heading-getting-to-know-the-sources-and-the-console-tabs"><strong>Getting to know the <code>Sources</code> and the <code>console</code> tabs.</strong></h4>
<p>These two tabs are the perhaps going to be your best friends while debugging. The <code>Sources</code> tab can be used to visualize all the scripts that’s on the webpage you are visiting. This tab has sections for the code window, file tree, call stack &amp; watch windows, etc.</p>
<p>The <code>console</code> tab is where all of the log output goes. Additionally you can use the console tab’s prompt to execute JavaScript code. Its kind of synonymous to the command prompt on Windows, or terminal on Linux.</p>
<p><em>Tip : Toggle the console anytime in the DevTools using <code>Esc</code> key.</em></p>
<h3 id="heading-2-common-shortcuts-and-features"><strong>2 : Common Shortcuts and features</strong></h3>
<p>While you can visit the <a target="_blank" href="https://developers.google.com/web/tools/chrome-devtools/iterate/inspect-styles/shortcuts">complete list of shortcuts</a>, below are a few that are most used:</p>
<p>Feature Windows, Linux Mac<br>Search for a keyword, regex is supported. <code>Ctrl</code>+<code>F``Cmd</code>+<code>F</code><br>Search and Open a file <code>Ctrl</code>+<code>P``Cmd</code>+<code>P</code><br>Jump to line <code>Ctrl</code>+<code>G</code>+<code>:line_no``Cmd</code>+<code>G</code>+<code>:line_no</code><br>Add a breakpoint <code>Ctrl</code>+<code>B</code>, or click on the line no.<code>Cmd</code>+<code>B</code>, or click on the line no.<br>Pause / resume script execution <code>F8</code> <code>F8</code><br>Step over next function call <code>F10</code> <code>F10</code><br>Step into next function call <code>F11</code> <code>F11</code></p>
<h3 id="heading-3-using-a-source-map-for-our-code"><strong>3 : Using a Source Map for our Code</strong></h3>
<p>One of the coolest feature that you will love is <a target="_blank" href="https://developer.chrome.com/devtools/docs/javascript-debugging#breakpoints-dynamic-javascript">debugging Dynamic Script</a>, on the fly, via <a target="_blank" href="https://developer.chrome.com/devtools/docs/javascript-debugging#source-maps">Source Maps</a>.</p>
<p>Every script can be visualized in the Source tab of the DevTools. The source tab has all the JavaScript source files. But the code from the code editor is executed via <code>eval()</code>in a container simply called a virtual machine(VM) within the browser process.</p>
<p>As you might have guessed by now is that our code is actually a script that doesn’t have a file name. So we don’t see that in the Source tab.</p>
<p><img src="https://forum.freecodecamp.com/images/emoji/emoji_one/sparkles.png?v=2" alt=":sparkles:" width="600" height="400" loading="lazy"></p>
<p><strong><em>Here comes the hack!</em></strong></p>
<p><img src="https://forum.freecodecamp.com/images/emoji/emoji_one/sparkles.png?v=2" alt=":sparkles:" width="600" height="400" loading="lazy"></p>
<p>We must leverage <code>Source Maps</code> to assign a name to the JavaScript from our editor. Its pretty simple:</p>
<p>Lets say we are on the <a target="_blank" href="https://www.freecodecamp.com/challenges/factorialize-a-number">Factorialize</a> challenge, and our code looks like this:</p>
<pre><code class="lang-text">function factorialize(num) {
  if(num &lt;= 1){
  ...
}
factorialize(5);
</code></pre>
<p>All we need to do is add <code>//# sourceURL=factorialize.js</code> to the top of the code, i.e the first line:</p>
<pre><code class="lang-text">//# sourceURL=factorialize.js

function factorialize(num) {
  if(num &lt;= 1){
  ...
</code></pre>
<p><img src="https://forum.freecodecamp.com/images/emoji/emoji_one/sparkles.png?v=2" alt=":sparkles:" width="600" height="400" loading="lazy"></p>
<p><strong><em>And Eureka that’s it!</em></strong></p>
<p><img src="https://forum.freecodecamp.com/images/emoji/emoji_one/sparkles.png?v=2" alt=":sparkles:" width="600" height="400" loading="lazy"></p>
<p>Now open up the DevTools and search for the file name. Add break points, Debug away and enjoy!</p>
<h2 id="heading-more-info-on-debugging">More info on debugging:</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/the-beginner-bug-squashing-guide/">Beginner's guide to bug squashing</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/debugging-javascript-for-beginners-5d4ac15dd1cd/">Debugging tips and tricks for beginners</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-go-beyond-console-log-and-get-the-most-out-of-your-browsers-debugging-console-e185256a1115/">How to get the most out of your browser's debugging console</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Store Data in Web Browser Storage - localStorage and sessionStorage Explained ]]>
                </title>
                <description>
                    <![CDATA[ In order to manage data handled by your web application, you do not necessarily need a database. The respective Browser Storage features are supported by Chrome (version 4 and higher), Mozilla Firefox (version 3.5 and higher) and Internet Explorer (v... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-store-data-in-web-browser-storage-localstorage-and-session-storage-explained/</link>
                <guid isPermaLink="false">66c354e4a6c3eebadae8d2cf</guid>
                
                    <category>
                        <![CDATA[ Browsers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ storage ]]>
                    </category>
                
                    <category>
                        <![CDATA[ toothbrush ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 01 Feb 2020 00:00:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9d02740569d1a4ca3567.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In order to manage data handled by your web application, you do not necessarily need a database. The respective Browser Storage features are supported by Chrome (version 4 and higher), Mozilla Firefox (version 3.5 and higher) and Internet Explorer (version 8 and higher), and a range of other browsers including those of iOS and Android.</p>
<p>There are two main possibilities for browser storage: localStorage and sessionStorage.</p>
<h2 id="heading-localstorage"><strong>localStorage</strong></h2>
<p>Any content/data saved to the <code>localStorage</code> object will be available after the browser has been restarted (closed and opened again). In order to <strong><em>save an item</em></strong> to <code>localStorage</code>, you can use the method <code>setItem()</code>. This method must be handed a key and a value.</p>
<pre><code class="lang-text">Example: localStorage.setItem("mykey","myvalue");
</code></pre>
<p>To <strong><em>retrieve the item from the localStorage</em></strong>, the method <code>getItem</code> must be used. The <code>getItem</code> method must be handed the key of the data you would like to retrieve:</p>
<pre><code class="lang-text">  Example: localStorage.getItem("mykey");
</code></pre>
<p>You can remove an item from <code>localStorage</code> by using the <code>removeItem()</code> method. This method must be handed the key of the item to be removed:</p>
<pre><code class="lang-text">  Example: localStorage.removeItem("mykey");
</code></pre>
<p>To clear the entire <code>localStorage</code>, you should use the <code>clear()</code> method on the <code>localStorage</code> object:</p>
<pre><code class="lang-text">  Example: localStorage.clear();
</code></pre>
<h2 id="heading-sessionstorage"><strong>sessionStorage</strong></h2>
<p>Items saved in the <code>sessionStorage</code> object will remain until the browser is closed by the user. Then, the storage will be cleared.</p>
<p>You can save an item to <code>sessionStorage</code>, please use the method <code>setItem()</code> on the <code>sessionStorage</code> object:</p>
<pre><code class="lang-text">Example: sessionStorage.setItem("mykey","myvalue");
</code></pre>
<p>To <strong><em>retrieve the item from the sessionStorage</em></strong>, the method <code>getItem</code> must be used. The <code>getItem</code> method must be handed the key of the data you would like to retrieve:</p>
<pre><code class="lang-text">  Example: sessionStorage.getItem("mykey");
</code></pre>
<p>You can remove an item from <code>sessionStorage</code> by using the <code>removeItem()</code> method. This method must be handed the key of the item to be removed:</p>
<pre><code class="lang-text">  Example: sessionStorage.removeItem("mykey");
</code></pre>
<p>To clear the entire <code>sessionStorage</code>, you should use the <code>clear()</code> method on the <code>sessionStorage</code> object:</p>
<pre><code class="lang-text">  Example: sessionStorage.clear();
</code></pre>
<h2 id="heading-saving-arrays-to-localstorage-and-sessionstorage"><strong>Saving arrays to localStorage and sessionStorage</strong></h2>
<p>You cannot just save single values to the <code>localStorage</code> and <code>sessionStorage</code>, but you can also save the content of an array.</p>
<p>In this example, we have an array with numbers:</p>
<pre><code class="lang-text">var ourArray =[1,2,3,4,5];
</code></pre>
<p>We can now save it to <code>localStorage</code> or <code>sessionStorage</code> using the <code>setItem()</code> method:</p>
<pre><code class="lang-text">localStorage.setItem("ourarraykey",JSON.stringify(ourArray));
</code></pre>
<p>or, for <code>sessionStorage</code>:</p>
<pre><code class="lang-text">sessionStorage.setItem("ourarraykey",JSON.stringify(ourArray));
</code></pre>
<p>In order to be saved, the array must first be converted to a string. In the example shown above, we are using the <code>JSON.stringify</code> method to accomplish this.</p>
<p>When retrieving our data from the <code>localStorage</code> or <code>sessionStorage</code>, convert it back to an array:</p>
<pre><code class="lang-text">var storedArray = localStorage.getItem("ourarraykey");
ourArray = JSON.parse(storedArray);
</code></pre>
<p>or, for <code>sessionStorage</code>:</p>
<pre><code class="lang-text">var storedArray = sessionStorage.getItem("ourarraykey");
ourArray = JSON.parse(storedArray);
</code></pre>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
