Skip to main content
Early access — new tools and guides added regularly
🟣 Power User Workflows — Guide 15 of 17
View track
>_ claude codeAdvanced30 min

Building Chrome Extensions with AI

Build a Chrome extension from scratch — manifest configuration, content scripts, popup UI, storage, and publishing to the Chrome Web Store.

What you will build
A published Chrome extension with popup UI, content scripts, and persistent storage

Chrome extension architecture

Chrome extensions are small programs that modify and enhance the browser experience. They can add buttons to the toolbar, modify web page content, intercept network requests, and communicate with external APIs. Understanding the architecture is essential because Chrome extensions have a unique execution model unlike web apps or Node.js programs. An extension has up to four components. The manifest (manifest.json) declares the extension's capabilities, permissions, and structure — it is the entry point Chrome reads. The popup is a small HTML page that appears when the user clicks the extension icon — good for settings, controls, and quick actions. Content scripts are JavaScript files that run inside web pages, with access to the page's DOM but in an isolated execution context. The service worker (background script) runs independently of any page, handles events, manages state, and coordinates between components. Ask Claude Code: Create a new directory for a Chrome extension project. Initialise it with a manifest.json using Manifest V3 (the current standard). Set the name to Enigmatica Page Analyser, version 1.0.0, description to Analyse any web page for readability, performance, and SEO. Add a browser_action with a default popup pointing to popup.html, a default icon at icons/icon48.png, and the permissions for activeTab and storage. Create a minimal popup.html that loads popup.js. Create a minimal content script at content.js that logs Extension loaded to the console. Load the extension in Chrome: go to chrome://extensions, enable Developer Mode, click Load Unpacked, and select your extension directory. You should see the extension icon in the toolbar. Click it to see the popup. Open any web page, open DevTools console, and see the Extension loaded message. This confirms all three components are working.

Building the popup interface

The popup is your extension's primary UI. It opens when the user clicks the extension icon and closes when they click elsewhere. The popup must be fast and focused — users expect instant results. Ask Claude Code: Build the popup UI in popup.html and popup.js. The popup shows a page analysis dashboard for the current tab. When the popup opens, it sends a message to the content script requesting page analysis. The content script reads the page's DOM and sends back: the page title, word count, estimated reading time (words divided by 200, rounded up), heading structure (H1, H2, H3 counts), image count (with and without alt text for accessibility), link count (internal and external), meta description (if present), and colour scheme detection (approximate primary colours used on the page). Display the results in the popup as a clean dashboard. Ask Claude Code: Style the popup with a fixed width of 360 pixels. Use a card-based layout with sections for Readability (reading time, word count, paragraph count), Structure (heading counts, image alt text percentage), SEO (meta description present or missing, heading hierarchy valid or broken, canonical URL present), and Links (total count, internal, external, broken detection would require network requests so skip for now). Add colour coding: green checkmarks for good metrics, yellow warnings for areas that could improve, and red alerts for issues. Use chrome.storage.local to remember the last analysis. Ask Claude Code: When the popup opens, immediately show the cached analysis for the current URL (instant loading), then run a fresh analysis in the background and update the display. Store analyses keyed by URL. Add a history feature that shows the last 10 analysed pages with their scores. Common error: the popup loses all state when it closes. Any JavaScript variables are gone. Use chrome.storage.local for persistence and message passing for communication with content scripts. Never assume popup state persists between openings.

Content scripts and page interaction

Content scripts run in the context of web pages. They can read and modify the DOM, inject elements, and observe changes. But they run in an isolated world — they cannot access the page's JavaScript variables or functions directly (this is a security feature). Ask Claude Code: Build a comprehensive page analyser in content.js. The content script should analyse the page when requested and when the page content changes (use a MutationObserver to detect dynamic content loading). Collect these metrics. Readability analysis: count words, sentences, and paragraphs. Calculate the Flesch-Kincaid readability score (a standard measure of text difficulty based on average sentence length and syllable count). Report the grade level (for example, Grade 8 means an average 13-year-old could understand it). Accessibility scan: find all images without alt text, find form inputs without labels, check colour contrast on text elements (compare the computed text colour against the computed background colour and flag ratios below WCAG AA standard of 4.5 to 1), and find interactive elements that are not keyboard focusable. Performance indicators: count the total number of DOM elements (pages with more than 1500 elements are considered heavy), count external scripts and stylesheets, detect render-blocking resources, and check if images have explicit width and height attributes (prevents layout shift). Ask Claude Code: Add a visual overlay mode. When the user clicks Highlight Issues in the popup, the content script injects a visual overlay onto the page. Images without alt text get a red dotted border and a tooltip saying Missing alt text. Low-contrast text gets a yellow background highlight. Headings that skip levels (H1 followed by H3 with no H2) get an orange indicator. Add a toggle to show and hide the overlay. Implement the message passing between popup and content script. Ask Claude Code: Use chrome.runtime.sendMessage (from content script to service worker) and chrome.tabs.sendMessage (from popup or service worker to content script). Define a message protocol with typed messages: ANALYSE_PAGE, ANALYSIS_RESULT, HIGHLIGHT_ISSUES, and CLEAR_HIGHLIGHTS. Each message has a type field and a payload field. Common error: content scripts cannot be injected on chrome:// pages, the Chrome Web Store, or other extension pages. Check the URL before sending messages and show a This page cannot be analysed message in the popup for restricted pages.

Service worker and background processing

The service worker runs in the background, independent of any tab or popup. It handles events, manages extension-wide state, and coordinates between components. In Manifest V3, the service worker is non-persistent — it starts when needed and stops when idle. Ask Claude Code: Create the service worker at background.js (or service-worker.js — declare it in the manifest under background.service_worker). Register event listeners for: chrome.runtime.onInstalled (runs when the extension is first installed or updated — use it to set default settings and show a welcome page), chrome.action.onClicked (runs when the extension icon is clicked if no popup is defined — we have a popup so this will not fire, but useful to know), and chrome.runtime.onMessage (receives messages from content scripts and the popup). Add context menu integration. Ask Claude Code: When the extension installs, add a right-click context menu item: Analyse This Page with Enigmatica. When clicked, the service worker sends a message to the content script on the active tab to run the analysis and then opens the popup with the results. This provides an alternative way to trigger analysis without clicking the toolbar icon. Build a scheduled analysis feature. Ask Claude Code: Use chrome.alarms to create a periodic task. Every hour, the service worker checks if any tabs have been open for more than 30 minutes and runs an automatic analysis. Store the results and show a notification badge on the extension icon when new results are available. The badge shows the count of pages analysed since the user last opened the popup. Add cross-tab state management. Ask Claude Code: Create a state manager in the service worker that tracks all open tabs and their analysis status. When a tab navigates to a new URL, mark its analysis as stale. When the content script reports a completed analysis, update the state. Provide this state to the popup so it can show a list of all open tabs with their analysis scores — like a mini dashboard of all your browsing. Common error: service workers in Manifest V3 can be terminated at any time by Chrome. Do not store state in JavaScript variables — they disappear when the service worker stops. Always use chrome.storage.local for persistent state. Use chrome.alarms for scheduled tasks instead of setInterval (which dies with the service worker).

Options page and user preferences

An options page lets users customise the extension's behaviour. Ask Claude Code: Create an options page at options.html with a corresponding options.js. Declare it in manifest.json under options_page. The options page should include these settings. Analysis preferences: which checks to run (readability, accessibility, SEO, performance — all enabled by default as checkboxes), the minimum contrast ratio to flag (default 4.5, adjustable for stricter WCAG AAA compliance at 7.0), and whether to auto-analyse pages on load or only on demand. Display preferences: overlay highlight colours (colour pickers for error, warning, and info highlights), popup theme (light or dark), and whether to show the badge count on the extension icon. Data preferences: how long to keep analysis history (7 days, 30 days, forever), whether to sync settings across Chrome instances using chrome.storage.sync (limited to 100KB but available on all logged-in Chrome browsers), and an export/import button for analysis history as JSON. Ask Claude Code: Build the options page with a clean, form-based layout. Use chrome.storage.sync for settings (synced across devices) and chrome.storage.local for analysis data (device-specific, larger storage limit). When settings are saved, notify all active content scripts to update their behaviour. Add keyboard shortcuts. Ask Claude Code: Declare keyboard shortcuts in the manifest under commands. Define a toggle-analysis shortcut (Ctrl+Shift+E on Windows, Cmd+Shift+E on Mac) that triggers analysis on the current page, and a toggle-overlay shortcut (Ctrl+Shift+H) that toggles the highlight overlay. Chrome handles the keyboard shortcut registration — you just define the command name and suggested key combination. Users can customise shortcuts at chrome://extensions/shortcuts. Add a first-run experience. Ask Claude Code: When the extension is installed for the first time, open a welcome page (a local HTML file included in the extension) that explains what the extension does, walks through the features with screenshots, and prompts the user to pin the extension to the toolbar. Common error: chrome.storage.sync has strict limits: 8KB per item, 100KB total, and 120 write operations per minute. Store large data (analysis results, history) in chrome.storage.local instead. Only use sync for small configuration objects like user preferences.

Testing, packaging, and Chrome Web Store publishing

Before publishing, thoroughly test the extension across different websites and configurations. Ask Claude Code: Create a testing checklist. Test the extension on 10 diverse websites: a text-heavy blog, a JavaScript-heavy SPA (like Gmail or Twitter), a media-heavy site (YouTube), a simple static page, an empty or minimal page, a page with many accessibility issues, a page behind authentication, an error page (404), a page with iframes, and a very long page with lazy-loaded content. For each site, verify: the analysis completes without errors, the results are accurate, the overlay highlights work correctly, the popup displays results cleanly, and no console errors appear. Test edge cases. Ask Claude Code: Test with: extremely large pages (over 10,000 DOM elements), pages that modify themselves constantly (live dashboards), multiple tabs open simultaneously, opening and closing the popup rapidly, and disabling and re-enabling the extension. Package the extension. Ask Claude Code: Create a build script that: copies all necessary files to a dist/ directory, minifies JavaScript for production (reduces extension size), optimises images, generates the required icon sizes (16x16, 32x32, 48x48, 128x128) from a single source image, validates the manifest against Chrome's requirements, and creates a .zip file ready for upload. Publish to the Chrome Web Store. Ask Claude Code: Walk me through the Chrome Web Store publishing process. You need a Chrome Web Store developer account (one-time 5 dollar registration fee). Upload the .zip file. Fill in the store listing: detailed description, screenshots of the extension in action (at least 2, recommended 5), category selection (Developer Tools for this extension), privacy policy URL (required — create a simple privacy policy page), and the permissions justification (explain why each permission is needed — Chrome reviews these carefully). After submission, the review process takes 1 to 3 business days. Common rejection reasons: requesting permissions not justified by the extension's functionality, no privacy policy, screenshots that do not match the actual extension, and code that loads remote scripts (Chrome prefers all code bundled in the extension). Common error: the Web Store listing description is limited to 132 characters for the short description and 16,000 characters for the detailed description. Use the short description as a value proposition and the detailed description for features, screenshots walkthrough, and FAQ.

Related Lesson

Browser Automation

This guide is hands-on and practical. The full curriculum covers the conceptual foundations in depth with structured lessons and quizzes.

Go to lesson