Claude Skills Guide

A Chrome extension site audit tool transforms your browser into a powerful debugging and analysis platform. Rather than switching between multiple applications, you can examine page performance, analyze DOM structure, check accessibility, and monitor network requests—all from a single extension popup. This guide shows you how to build these tools and use them effectively in your development workflow.

Why Build a Site Audit Extension?

Browser developer tools cover many auditing needs, but they require multiple panels and constant context switching. A custom Chrome extension consolidates the checks you run most often into one interface. You decide which audits matter for your projects—whether that means checking meta tags, measuring render blocking resources, or validating HTML structure.

Extensions also benefit teams. Share your audit tool with colleagues to standardize code reviews and catch issues before deployment. The investment in building a custom tool pays dividends in consistency and time savings.

Core Components of a Site Audit Extension

Every audit extension needs three main pieces: the manifest file, a background script for persistent logic, and a popup interface for user interaction.

Manifest Configuration

Your manifest.json defines permissions and declares which files Chrome should load:

{
  "manifest_version": 3,
  "name": "Site Audit Tool",
  "version": "1.0",
  "permissions": ["activeTab", "scripting", "storage"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon.png"
  },
  "host_permissions": ["<all_urls>"]
}

The activeTab permission lets your extension access the current page when the user invokes it. Use scripting to inject content scripts that analyze the page. The host_permissions field grants access to website data across all URLs.

Content Script for Page Analysis

Content scripts run in the context of the target page, giving you full access to the DOM and JavaScript variables:

// content.js - Runs in page context
function auditPage() {
  const results = {
    title: document.title,
    metaDescription: document.querySelector('meta[name="description"]')?.content || 'Missing',
    headingStructure: analyzeHeadings(),
    imagesWithoutAlt: findMissingAltTexts(),
    links: countLinks(),
    scripts: analyzeScripts()
  };
  
  return results;
}

function analyzeHeadings() {
  const headings = {
    h1: document.querySelectorAll('h1').length,
    h2: document.querySelectorAll('h2').length,
    others: document.querySelectorAll('h3, h4, h5, h6').length
  };
  return headings;
}

function findMissingAltTexts() {
  const images = document.querySelectorAll('img');
  return Array.from(images)
    .filter(img => !img.alt || img.alt.trim() === '')
    .map(img => ({ src: img.src, alt: img.alt }));
}

function countLinks() {
  const links = document.querySelectorAll('a[href]');
  const external = Array.from(links).filter(a => a.href.startsWith('http') && !a.href.includes(location.hostname));
  return { total: links.length, external: external.length };
}

function analyzeScripts() {
  const scripts = document.querySelectorAll('script');
  return {
    total: scripts.length,
    async: Array.from(scripts).filter(s => s.async).length,
    deferred: Array.from(scripts).filter(s => s.defer).length
  };
}

This script extracts structural information about the page. You can expand it to measure performance metrics, check color contrast, or validate schema markup.

The popup provides the user-facing interface:

<!-- popup.html -->
<!DOCTYPE html>
<html>
<head>
  <style>
    body { width: 400px; padding: 16px; font-family: system-ui, sans-serif; }
    .audit-section { margin-bottom: 16px; }
    .audit-section h3 { margin: 0 0 8px; font-size: 14px; }
    .result { padding: 8px; background: #f5f5f5; border-radius: 4px; }
    .warning { background: #fff3cd; }
    .error { background: #f8d7da; }
    button { width: 100%; padding: 8px; cursor: pointer; }
  </style>
</head>
<body>
  <h2>Site Audit Tool</h2>
  <button id="runAudit">Run Audit</button>
  <div id="results"></div>
  <script src="popup.js"></script>
</body>
</html>
// popup.js
document.getElementById('runAudit').addEventListener('click', async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    function: auditPage
  }, (results) => {
    displayResults(results[0].result);
  });
});

function displayResults(data) {
  const container = document.getElementById('results');
  container.innerHTML = `
    <div class="audit-section">
      <h3>Page Title</h3>
      <div class="result">${data.title || 'Missing'}</div>
    </div>
    <div class="audit-section">
      <h3>Meta Description</h3>
      <div class="result ${!data.metaDescription || data.metaDescription === 'Missing' ? 'warning' : ''}">
        ${data.metaDescription.substring(0, 100)}...
      </div>
    </div>
    <div class="audit-section">
      <h3>Heading Structure</h3>
      <div class="result">
        H1: ${data.headingStructure.h1} | H2: ${data.headingStructure.h2}
      </div>
    </div>
    <div class="audit-section">
      <h3>Images Missing Alt Text</h3>
      <div class="result ${data.imagesWithoutAlt.length > 0 ? 'warning' : ''}">
        ${data.imagesWithoutAlt.length} images
      </div>
    </div>
  `;
}

Advanced Audit Capabilities

Beyond basic DOM analysis, extend your tool with performance and network auditing.

Performance Metrics

Use the Performance API to capture timing data:

function measurePerformance() {
  const timing = performance.timing;
  const metrics = {
    pageLoadTime: timing.loadEventEnd - timing.navigationStart,
    domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,
    firstPaint: performance.getEntriesByType('paint')[0]?.startTime || 0,
    domInteractive: timing.domInteractive - timing.navigationStart
  };
  
  const resources = performance.getEntriesByType('resource');
  const largeResources = resources.filter(r => r.transferSize > 100000);
  
  return { metrics, largeResources };
}

Network Request Analysis

The chrome.devtools.network API lets you capture HTTP requests:

chrome.devtools.network.onRequestFinished.addListener(request => {
  const auditEntry = {
    url: request.request.url,
    method: request.request.method,
    status: request.response.status,
    size: request.response.bodySize,
    time: request.time
  };
  
  // Flag slow or failed requests
  if (request.time > 1000) {
    console.warn('Slow request:', auditEntry);
  }
});

Practical Applications

Site audit tools serve various workflows. E-commerce developers verify product pages include proper structured data and meta tags. Marketing teams check that landing pages have correct Open Graph metadata for social sharing. Accessibility auditors quickly identify images missing alt text across large sites.

You can also integrate API checks. Query your backend endpoints from the extension and validate responses without leaving the browser:

async function auditApiHealth() {
  const endpoints = [
    '/api/health',
    '/api/users/count',
    '/api/products'
  ];
  
  const results = await Promise.all(
    endpoints.map(async endpoint => {
      const start = Date.now();
      try {
        const response = await fetch(endpoint);
        return {
          endpoint,
          status: response.ok,
          latency: Date.now() - start
        };
      } catch (error) {
        return { endpoint, status: false, error: error.message };
      }
    })
  );
  
  return results;
}

Loading and Testing Your Extension

After creating your files, load the extension in Chrome by visiting chrome://extensions/, enabling Developer mode, and clicking “Load unpacked”. Select your extension directory.

Test incrementally. Verify the popup opens, then confirm the content script executes, then add more complex audits. Use console.log statements in your scripts and view output in the Chrome DevTools console for the respective context.

Extending for Team Use

Package your extension for internal distribution by creating a ZIP file of your directory. Team members load it the same way during development. For wider distribution, publish to the Chrome Web Store after creating developer account credentials.

Version your extension semantically and document changes in a CHANGELOG.md file. This practice helps teammates understand what changed between updates and why certain audits were added or modified.

Building a custom Chrome extension site audit tool gives you precise control over the checks that matter for your projects. Start with simple DOM audits and gradually add performance monitoring, API validation, and accessibility checks. The result is a personalized toolkit that accelerates your development workflow and helps maintain quality standards across your work.

Built by theluckystrike — More at zovo.one