DEV Community

Cover image for How to Change a Webpage UI with a Chrome Extension
Divyansh Singh for OpenSauced

Posted on

How to Change a Webpage UI with a Chrome Extension

Have you ever wondered how chrome extensions can change the UI of some of your favorite websites, like YouTube and GitHub? Chrome extensions can be a powerful tool for boosting productivity, helping you to debug code, and sometimes just plain fun. Hopefully, by the end of this blog post, you'll have an idea of how the magic happens, and how you can use content scripts to create your own UI magic through a chrome extension. I'll walk you through the process of how we do it using the OpenSauced.ai chrome extension. If you want to do a deep dive into the extension, there's a link to the repository at the end of this post.

The OpenSauced.ai chrome extension is a versatile tool that helps both open source maintainers and contributors increase their productivity. It uses AI tools and integrates smoothly with the OpenSauced platform to enhance discoverability.

This extension modifies the GitHub web page and adds helpful elements with features to facilitate code reviews, enable direct interaction with OpenSauced on GitHub, and provide additional functionalities such as generating tests and explaining code.

One such injected element in action

But how does that work exactly? How can a chrome extension insert UI elements into a webpage? 🤔

DOMination: Unleashing the Power of Content Scripts

This is where content scripts play a crucial role. Content scripts are a feature provided by Chrome extensions that allow them to manipulate and modify the DOM (Document Object Model) of a webpage. They act as a bridge between the extension and the webpage, enabling the injection of UI elements seamlessly. By utilizing content scripts, the OpenSauced.ai chrome extension is able to add its useful features and enhance the user experience on GitHub.

Creating a content script for a Chrome Extension

You can create your content script, a standard JavaScript/TypeScript file in the src/ folder for you chrome extension, we later discuss how you register it in manifest.json in the root.

Content scripts can read details of the web pages the browser visits, make changes to them, and pass information to their parent extension. Therefore, we can read the current URL and perform various actions based on the page the user is on!

In the OpenSauced.ai chrome extension, we use this information to decide which element needs to be injected into the page. The "View on OpenSauced" button, for example, should be injected if the current page is a profile page, and the various PR review features should only be injected when the current page is a code review page.

All your conditionals and injections should go inside this content-script. Here's an example snippet from the OpenSauced.ai chrome extension:

if (isGithubProfilePage(window.location.href)) {
        const username = getGithubUsername(window.location.href);

        if (!username) {
            return;
        }
        if (await isOpenSaucedUser(username)) {
            injectViewOnOpenSauced(username);
        }
}
Enter fullscreen mode Exit fullscreen mode

This code checks if the current page is a GitHub profile page, like github.com/diivi, and renders the "View on OpenSauced" button if the user exists on OpenSauced too, easy!

Injecting a custom UI component into the webpage💉

Injecting components into the DOM is as simple as creating a Node through JavaScript's createElement function, and adding it to the DOM by using any method that you like-we use the appendChild method-but there's also insertBefore and other similar methods. Here's a usage example from the OpenSauced.ai chrome extension:

const injectViewOnOpenSaucedButton = (username: string) => {
    if (document.getElementById("view-on-opensauced-button")) {
        return;
    }
Enter fullscreen mode Exit fullscreen mode

This section handles duplicate nodes: we add an id to the node and if a node already exists with that id in the DOM (due to rerenders or other technical issues), we don't append the Node to the DOM again.

    const viewOnOpenSaucedButton = ViewOnOpenSaucedButton(username);
Enter fullscreen mode Exit fullscreen mode

The ViewOnOpenSaucedButton is a component (Node) that has all HTML, CSS and JS for the "View on OpenSauced Button". We have separated the view from the logic here.

    const userBio = document.querySelector(
        `${GITHUB_PROFILE_USER_PROFILE_BIO_SELECTOR}, ${GITHUB_PROFILE_EDIT_MENU_SELECTOR}`,
    );

    userBio?.append(viewOnOpenSaucedButton);
};
Enter fullscreen mode Exit fullscreen mode

Since we have access to the webpage's DOM, we can find the component we want to inject our Node into, and use the append method to actually inject it.

Registering the Script 📜

Content scripts are registered in the manifest.json file under the "content_scripts" field, like so:

{
 "name": "OpenSauced.ai",
 ...
 "content_scripts": [
   {
      "js": ["src/content-scripts/github.ts"],
      "matches": ["https://github.com/*"],
       ...
   }
 ],
 ...
}
Enter fullscreen mode Exit fullscreen mode

This is a snippet from the OpenSauced.ai chrome extension's manifest.json file. Here, the js key expects an array of the paths where the content scripts to be executed reside, and the matches key expects an array of URLs of the webpages which this content script will be injected into.

Now we run the extension, and voila! 🎉

View on OpenSauced Button result

The button is successfully injected right where I wanted it!

There are a lot of different possibilities for what you can do if you create your own chrome extension. You can find the full code for our chrome extension in our open-sauced/ai repo. As you've seen from the gif at the top of this blog post, our extension has features for refactoring code, writing tests, and explaining code. You can also interact with OpenSauced highlights and more. But there are so many different options for what chrome extensions can do, like adding gifs to your PRs or for interacting with posts online. What have been the most interesting features you've seen in a chrome extension.

Top comments (7)

Collapse
 
mayhul_jindal profile image
mayhul

Dem 🔥🔥

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍

Collapse
 
diivi profile image
Divyansh Singh

Thanks for the recognition!

Collapse
 
levischouten profile image
Levi Schouten

Really interesting!

Collapse
 
aryaman_ profile image
Aryaman Sharma

Found exactly what I was looking for my next project.🙌

Collapse
 
punyamsingh profile image
Punyam Singh

Open-Sauced gave me the boost I needed in my coding journey.
it's wonderful to use.

Collapse
 
d3v1na profile image
Devina Bhatnagar

Really insightful! Thanks!