How to Make your Own HTML Cleaner Chrome Extension

How to Make your Own HTML Cleaner Chrome Extension

Below is a step-by-step guide on how to build a simple HTML Cleaner Chrome Extension.

HTML Cleaner Chrome Extension

In short, this is a Google Chrome extension that runs on your local machine and allows you to paste raw HTML, strip it of unwanted tags and attributes, and then copy the cleaned result. This tool is useful for quickly tidying up HTML that contains extra classes, inline styles, or script tags that you don’t need. 

Introduction

Cleaning up HTML can be time-consuming if you manually remove every class, style, or script. Using a custom Chrome extension simplifies the process: just paste your raw HTML, click “CLEAN,” and then copy the cleaned output. This tutorial walks you through creating such an extension from scratch.

Prerequisites

  1. A basic understanding of HTML, CSS, and JavaScript.
  2. Google Chrome installed on your machine.
  3. Icons (optional) if you want your extension to have a unique icon in the browser toolbar (16×16, 48×48, 128×128 PNGs).

Folder Structure

Create a folder where you’ll keep all extension-related files. For instance:

html-cleaner-extension
├── manifest.json
├── popup.html
├── popup.js
└── icons (optional folder for icon images)

You can name the folder anything you like (for example, “html-cleaner-extension”).

Alright, let’s get our hands dirty (with code).

Create an HTML Cleaner Chrome Extension and Run it Locally

Step 1: Create the Manifest File (manifest.json)

Chrome extensions require a manifest.json file to define their configuration. Here is an example of a Manifest V3 file that sets up the extension name, version, popup, and icons:

{
  "name": "HTML Cleaner Extension",
  "version": "1.0",
  "manifest_version": 3,
  "description": "A simple tool to paste raw HTML, clean it, and copy the result.",
  
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  }
}

Explanation:

  • manifest_version: Must be set to 3 for modern Chrome extensions.
  • name, version, description: Basic metadata.
  • icons: Optional but recommended. Points to icon files you’d place in an icons subfolder.
  • action: Defines what happens when the user clicks the extension’s icon. default_popup is set to popup.html, meaning Chrome will display that file in a popup window. default_icon sets the icons that appear in the toolbar and extensions page.

Step 2: Create the Popup HTML (popup.html)

This file defines the user interface of the extension’s popup. It contains two textareas (one for input, one for output) and two buttons (one to clean, one to copy).

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>HTML Cleaner Extension</title>
  <style>
    body {
      font-family: sans-serif;
      margin: 0;
      padding: 0.75rem;
      width: 400px;
      box-sizing: border-box;
    }
    h2 {
      margin: 0 0 0.5rem;
      font-size: 1.2rem;
    }
    textarea {
      width: 100%;
      height: 120px;
      box-sizing: border-box;
      margin-bottom: 0.5rem;
    }
    button {
      margin-right: 8px;
      padding: 6px 12px;
      font-size: 0.9rem;
      cursor: pointer;
    }
    .row {
      margin-bottom: 0.5rem;
    }
  </style>
</head>
<body>
  <h2>HTML Cleaner</h2>
  <div class="row">
    <textarea id="inputHTML" placeholder="Paste your raw HTML here..."></textarea>
  </div>
  <div class="row">
    <button id="cleanBtn">CLEAN</button>
  </div>
  <div class="row">
    <textarea id="outputHTML" placeholder="Cleaned HTML will appear here..." readonly></textarea>
  </div>
  <div class="row">
    <button id="copyBtn">COPY CLEANED CODE</button>
  </div>

  <script src="popup.js"></script>
</body>
</html>

Explanation:

  • Two textareas:
    • inputHTML: Where you paste raw HTML that needs cleaning.
    • outputHTML: Displays the cleaned HTML (set to readonly so users can’t accidentally modify it).
  • Two buttons:
    • cleanBtn: Executes the cleaning logic.
    • copyBtn: Copies the cleaned result to the clipboard.

Step 3: Create the Script File (popup.js)

This JavaScript file performs the cleaning of HTML and handles button clicks:

// List of allowed tags
const ALLOWED_TAGS = [
  'HTML', 'HEAD', 'BODY',
  'TITLE', 'META',  // Optional, if you want minimal head info
  'P', 'BR', 'HR',
  'STRONG', 'EM', 'B', 'I', 'U', 'SMALL', 'SPAN',
  'UL', 'OL', 'LI',
  'TABLE', 'TR', 'TD', 'TH',
  'A', 'IMG',
  'H1', 'H2', 'H3', 'H4', 'H5', 'H6'
];

// Allowed attributes for particular tags
const ALLOWED_ATTRIBUTES = {
  'A': ['href', 'title'],
  'IMG': ['src', 'alt', 'title', 'width', 'height']
};

// Tags that you want to remove entirely, including their content
const REMOVE_TAGS = ['SCRIPT', 'STYLE', 'IFRAME', 'LINK', 'META', 'NOSCRIPT', 'EMBED', 'OBJECT'];

/**
 * Cleans the given HTML string.
 */
function cleanHTML(rawHTML) {
  // Parse the HTML string into a DOM
  const parser = new DOMParser();
  const doc = parser.parseFromString(rawHTML, 'text/html');

  // 1. Remove specific tags (script, style, etc.)
  REMOVE_TAGS.forEach(tag => {
    doc.querySelectorAll(tag).forEach(el => el.remove());
  });

  // 2. Remove all comment nodes
  removeComments(doc);

  // 3. Unwrap disallowed tags (keep content, remove tag)
  unwrapDisallowedTags(doc);

  // 4. Strip attributes from allowed tags, removing everything else
  stripAttributes(doc);

  // Return the cleaned HTML
  return doc.documentElement.outerHTML;
}

/**
 * Removes all HTML comments from the document.
 */
function removeComments(doc) {
  const walker = doc.createTreeWalker(doc, NodeFilter.SHOW_COMMENT, null);
  const toRemove = [];
  let current;
  while ((current = walker.nextNode())) {
    toRemove.push(current);
  }
  toRemove.forEach(node => node.remove());
}

/**
 * For elements not in ALLOWED_TAGS, remove the tag but keep its children.
 */
function unwrapDisallowedTags(doc) {
  let changed = true;
  while (changed) {
    changed = false;
    const allElements = doc.querySelectorAll('*');
    allElements.forEach(el => {
      if (!ALLOWED_TAGS.includes(el.tagName.toUpperCase())) {
        changed = true;
        while (el.firstChild) {
          el.parentNode.insertBefore(el.firstChild, el);
        }
        el.remove();
      }
    });
  }
}

/**
 * Removes any attributes not explicitly allowed for each tag.
 */
function stripAttributes(doc) {
  const allElements = doc.querySelectorAll('*');
  allElements.forEach(el => {
    const tagName = el.tagName.toUpperCase();
    const allowed = ALLOWED_ATTRIBUTES[tagName] || [];
    const removeList = [];
    for (let i = 0; i < el.attributes.length; i++) {
      const attrName = el.attributes[i].name;
      if (!allowed.includes(attrName)) {
        removeList.push(attrName);
      }
    }
    removeList.forEach(attr => el.removeAttribute(attr));
  });
}

/**
 * When user clicks CLEAN:
 * 1. Grab raw HTML from input box.
 * 2. Clean it.
 * 3. Display cleaned result in output box.
 */
document.getElementById('cleanBtn').addEventListener('click', () => {
  const rawHTML = document.getElementById('inputHTML').value;
  const cleaned = cleanHTML(rawHTML);
  document.getElementById('outputHTML').value = cleaned;
});

/**
 * When user clicks COPY:
 * 1. Select the text in the output box.
 * 2. Copy it to the clipboard.
 */
document.getElementById('copyBtn').addEventListener('click', () => {
  const outputField = document.getElementById('outputHTML');
  outputField.select();
  outputField.setSelectionRange(0, 99999); // for mobile devices
  document.execCommand('copy');
  alert('Cleaned HTML copied to clipboard!');
});

Explanation of Key Parts:

  • ALLOWED_TAGS: Lists the tags you want to keep in the final output.
  • ALLOWED_ATTRIBUTES: Defines which attributes are permitted on specific tags. For example, only href and title are kept for <a> tags.
  • REMOVE_TAGS: Defines tags you want to fully remove, including their child content (like <script> or <style>).
  • unwrapDisallowedTags: Any element not in ALLOWED_TAGS is removed, but its child text or elements are preserved.
  • stripAttributes: Removes all attributes except those listed in ALLOWED_ATTRIBUTES.

Step 4: Load the Extension in Chrome

  1. Open Chrome and go to chrome://extensions/.
  2. Enable Developer Mode by flipping the toggle in the top right corner.
  3. Click the “Load Unpacked” button.
  4. Navigate to your html-cleaner-extension folder and select it.
  5. The extension should now appear in your list of installed extensions.

Step 5: Use the Extension

  1. Pin the extension if desired, so its icon is visible in your toolbar.
  2. Click on the extension icon to open the popup window.
  3. Paste your raw HTML into the top box.
  4. Click the “CLEAN” button. Unwanted tags, attributes, and comments are removed.
  5. Check your cleaned HTML in the output box.
  6. Click “COPY CLEANED CODE” to copy the cleaned version to your clipboard.

Why Run a Chrome Extension Locally?

Running the extension locally (as opposed to installing from the Chrome Web Store) comes with several advantages:

  1. Offline Usage

    • You can continue using the tool even without an internet connection, since all code is stored locally on your machine.
  2. Security

    • You fully control and can inspect the code yourself. There’s no need to trust a third-party developer or worry about malicious updates, because it never touches any external servers.
  3. Ease of Updates

    • You can quickly modify any part of the code (e.g., adding new allowed tags or attributes) without waiting for a store approval process. Simply edit the files, reload the extension, and test your changes right away.
  4. Faster Debugging

    • Since you own all the code and resources, you can open the browser’s DevTools for the extension’s popup, debug any issues on the fly, and immediately see the results.
  5. Privacy

    • Your pasted HTML never leaves your local computer. This is especially important if you work with sensitive or proprietary content.

Locally running your Chrome extension gives you maximum flexibility and peace of mind. You control updates, features, and security, all without needing to rely on the public Chrome Web Store.

Customization Ideas

  1. If you need to allow certain new tags or attributes, add them to ALLOWED_TAGS or ALLOWED_ATTRIBUTES.
  2. If you want to keep certain tags instead of removing them entirely (for instance, <iframe> content), either remove it from REMOVE_TAGS or add it to ALLOWED_TAGS.
  3. If you prefer to remove disallowed tags and their children entirely (rather than preserving inner text), you can replace the unwrapping logic with a simple el.remove().

HTML cleaner chrome extension UI

Conclusion

By following these steps, you create a handy Chrome extension that cleans up pasted HTML in seconds. This saves you the hassle of manually stripping out classes, event handlers, or other extraneous elements from HTML snippets. With minimal code adjustments, you can customize the set of allowed tags and attributes for your particular use case.

Feel free to share this tutorial so that others looking to simplify or sanitize HTML can benefit from a quick and convenient tool right inside Chrome. Enjoy cleaner code with just a couple of clicks!

Share
Share
Website maintenance by: dp