DEV Community

Cover image for 🔥 Build Your Own AI-Powered Chrome Extension 🧩
Santhosh Vijayabaskar
Santhosh Vijayabaskar

Posted on

🔥 Build Your Own AI-Powered Chrome Extension 🧩

Ever find yourself scrolling through endless articles and news pages, just hoping to get the main points and move on? Yeah, me too. It’s exhausting, right? 😩 Well, here’s a little shortcut we’re going to build together! 💪

We’re going to make a Chrome extension that scrapes content from any webpage 🌐, whips up a quick summary with a bit of AI magic 🪄, and—here’s the fun part—reads it out loud for you 🔊. Super convenient, don’t you think?

By the end, you’ll have something that not only saves you time ⏱️ but also gives you that little boost of, ‘Hey, I built this!’ 😎

Here’s what we’re working with:

  1. Cheerio: Think of Cheerio as the friend that helps us skim through HTML and grab the important stuff. It’ll make sure we’re only pulling what we need from each page.
  2. Hugging Face Transformers: These AI models do the heavy lifting with summarization. We’ll use them to shrink long pages down to the essentials—no unnecessary fluff.
  3. ResponsiveVoice.js: This adds the final touch by reading out the summary. It’s surprisingly simple to use, and there are lots of voices and languages to pick from.

By the end, you’ll have built an AI-powered Chrome extension, and along the way, you’ll pick up some solid skills in JavaScript, web scraping, and using AI models. Don’t worry if you’re new to this—I’ll guide you through it, and by the end, you’ll have something genuinely cool and useful to show off. Let’s get started! 🚀


🪄 Step 1: Setting Up Your Chrome Extension

First, let’s get the basic Chrome extension structure in place. We’ll create three files for this setup:

  • manifest.json - Configures our Chrome extension.
  • popup.html - The user interface for the extension.
  • popup.js - Contains JavaScript code to interact with the content and run summarization.

Create the Project Structure

Set up your project folder with the following structure:

/summarize-tool
|-- manifest.json
|-- popup.html
|-- popup.js
Enter fullscreen mode Exit fullscreen mode

1.1 manifest.json: The Blueprint of Your Extension
The manifest file is what Chrome reads to know how to run and interact with our extension. Here’s what it should look like:

{
  "manifest_version": 3,
  "name": "Summarize Tool",
  "version": "1.0",
  "description": "A Chrome extension that scrapes and summarizes content from any webpage.",
  "permissions": ["scripting", "tabs", "activeTab"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "host_permissions": ["<all_urls>"]
}
Enter fullscreen mode Exit fullscreen mode

This setup tells Chrome what the extension does, which files are in use, and what permissions it needs (like accessing the current webpage’s content).

1.2 popup.html: Creating the Extension Interface
Now let’s add some basic HTML to give users a button to trigger the summarization and text-to-voice features.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Summarize Tool</title>
</head>
<body>
    <h2>Summarize This Page</h2>
    <button id="summarize-btn">Summarize</button>
    <div id="summary" style="margin-top: 15px; font-size: 14px;"></div>
    <button id="read-summary" style="margin-top: 15px;">Read Out Loud</button>
    <script src="popup.js"></script>
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

This simple layout gives us two buttons: one for summarizing the page and another for reading the summary out loud.

🔍 Step 2: Extracting Content with DOMParser

Now that our extension is set up, let’s dive into getting the content we want from any webpage. We’ll use DOMParser to retrieve and parse HTML directly in the Chrome extension environment.

🤔 Why DOMParser?
DOMParser allows us to extract the main text from a webpage without needing external libraries, making it efficient and compatible with Chrome extensions.

Here’s what we’ll do:

When the "Summarize" button is clicked, the DOMParser will grab the main content on the page.
This content will then be passed along to Hugging Face for summarization.
Here’s the code for popup.js to extract the content:

document.getElementById("summarize-btn").addEventListener("click", async () => {
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

    chrome.scripting.executeScript({
        target: { tabId: tab.id },
        func: getPageContent,
    }, (results) => {
        if (results && results[0] && results[0].result) {
            const htmlContent = results[0].result;
            parseAndSummarizeContent(htmlContent);
        }
    });
});

// Function to retrieve the page’s HTML content
function getPageContent() {
    return document.documentElement.outerHTML;
}

// Function to parse the HTML content and extract the main text
function parseAndSummarizeContent(htmlContent) {
    const parser = new DOMParser();
    const doc = parser.parseFromString(htmlContent, "text/html");

    // Extract specific elements or paragraphs
    const paragraphs = Array.from(doc.querySelectorAll("p"));
    let bodyText = paragraphs.slice(0, 3).map(p => p.innerText).join(" ");

    // Limit to 500 characters for API to prevent server errors
    if (bodyText.length > 500) {
        bodyText = bodyText.substring(0, 500);
    }

    // Send the trimmed text for summarization
    summarizeContent(bodyText);
}
Enter fullscreen mode Exit fullscreen mode

Now, whenever the button is clicked, this function will grab the main content of the page, trimmed to avoid API overload.

🧠 Step 3: Summarizing Content with Hugging Face Transformers

Next up, let’s condense that content with Hugging Face Transformers!

🤔 Why Hugging Face?
Hugging Face provides AI models that can do heavy-duty tasks, like turning a long article into a short summary. We’ll use their summarizer model to cut down the text into the key points.

To do this, you’ll need an API key from Hugging Face. Once you have that, here’s how to set up the API call in popup.js:

async function summarizeContent(content, retries = 3, delay = 1000) {
    const API_URL = "https://api-inference.huggingface.co/models/sshleifer/distilbart-cnn-12-6";
    const API_KEY = "YOUR_HUGGING_FACE_API_KEY";

    console.log("Sending content to summarize:", content); // Log the content being sent

    for (let attempt = 1; attempt <= retries; attempt++) {
        try {
            const response = await fetch(API_URL, {
                method: "POST",
                headers: {
                    "Authorization": `Bearer ${API_KEY}`,
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({ inputs: content })
            });

            if (response.ok) {
                const summaryData = await response.json();
                const summary = summaryData[0]?.summary_text || "Summary not available.";
                document.getElementById("summary").innerText = summary;
                return;
            } else if (response.status === 503) {
                console.error(`Attempt ${attempt}: Server unavailable (503). Retrying in ${delay}ms...`);
                await new Promise(resolve => setTimeout(resolve, delay));
                delay *= 2; // Exponential backoff
            } else {
                console.error("Error in response:", response.status, response.statusText);
                document.getElementById("summary").innerText = "Error: Unable to fetch summary.";
                return;
            }

        } catch (error) {
            console.error("Error:", error);
            document.getElementById("summary").innerText = "Error: Unable to fetch summary.";
            return;
        }
    }

    document.getElementById("summary").innerText = "Error: Unable to fetch summary after multiple attempts.";
}
Enter fullscreen mode Exit fullscreen mode

This code sends the content to Hugging Face, and the response will be a short summary that gets displayed in our popup. Now you’ve got the power of AI summarization with retry logic!

🔊 Step 4: Adding Text-to-Voice with Web Speech API

Let’s add the finishing touch by allowing users to hear the summary! The Web Speech API provides a simple way to convert text to speech directly in the browser.

In popup.js, add the functionality to read out the summary:

document.getElementById("read-summary").addEventListener("click", () => {
    const summaryText = document.getElementById("summary").innerText;
    if (summaryText) {
        const utterance = new SpeechSynthesisUtterance(summaryText);
        utterance.lang = "en-US"; // Adjust language as needed
        window.speechSynthesis.speak(utterance);
    } else {
        alert("No summary available to read.");
    }
});
Enter fullscreen mode Exit fullscreen mode

Now when you click “Read Out Loud,” the summary will be spoken, giving you a hands-free experience!

Step 5: Testing the Extension 🚀

Time to see it in action!

Head over to chrome://extensions/, enable Developer Mode, and click Load unpacked to load your extension.

Image description

Now, open a webpage, click the extension icon, and test the summarization and voice features.

Image description

It’s a good idea to test on different pages to make sure it’s working smoothly.

✨ Step 6: Fine-Tuning and Enhancements

Here are a few ideas to make this extension even better:

  • Experiment with Summarization Models: Hugging Face has different models, so try others to see if one works better for your needs.

  • Add a Language Selector: ResponsiveVoice supports multiple languages, so why not add a selector for users who prefer a different language?

  • Adjust Summary Length: Give users the option to choose between short, medium, and long summaries for more customization.

And that’s it! 🎉 You’ve built a powerful, time-saving Chrome extension that combines scraping, summarizing, and text-to-speech. Not only does it save time, but it’s also a tool you can genuinely use every day. Enjoy showing off your creation!

P.S.: I ran into a few NPM errors specific to my setup—if you hit any snags, feel free to reach out for help!

🌐 You can also learn more about my work and projects at https://santhoshvijayabaskar.com


Credits:
Photo by Firmbee.com on Unsplash

Top comments (0)