Chrome extensions have become an integral part of the browsing experience, allowing users to enhance and customize their web interactions. In this tutorial, I will guide you step-by-step in building your own Chrome extension using ChatGPT. We will explore how to leverage the language model’s capabilities to automate the code generation process. As I take you through each step, I will be building a simple Chrome extension using ChatGPT, for demonstration purposes, so that you can follow along. The Chrome extension I will be building will be referred to as βURL Saverβ and it allows users to:
- Save the URL of the website theyβre currently on.
- Add a title for every URL they want to save.
- View a list of all saved URLβs once clicking on the extension.
- Save a maximum of 20 URLβs.
- Delete any URL from the list by clicking on a cross that appears next to each item.
Pre-requisites: This tutorial is targeted at those who have a beginner to intermediate knowledge of coding and development. You will need to familiarize yourself with Googleβs documentation on how to migrate Chrome extensions from Manifest Version 2 to Manifest Version 3. Everything else will be clearly explained in this tutorial.
The Architecture Behind a Chrome Extension
Before I launch into the tutorial, I am going to provide a brief overview of all the files that could make up a Chrome extension. This is important because you will need to know which files to ask ChatGPT to write code for, depending on what you want your extension to do. Furthermore, from time-to-time ChatGPT does produce code with bugs. Therefore, knowing the function of each file can help you identify which file the issue is in if your extension does not perform as expected. Letβs start off with the manifest.json file.
manifest.json
The manifest file is a JSON file that defines the basic properties of your extension, such as its name, description, version, permissions, and background page. It is also used to declare the extension’s content scripts and service workers.
service-worker.js
The service worker file is a JavaScript file that defines the extension’s service worker. A service worker is a background process that can handle network requests and other tasks even when the extension is not active. This can improve the performance of your extension and allow it to work offline.
content-script.js
The content script file is a JavaScript file that can be injected into web pages. Content scripts can be used to:
- Modify the content of web pages.
- Add new functionality.
- Track user activity.
popup Files
The popup.css file is a CSS file that defines the style of the extension’s popup window. It determines the visual appearance of the window when it appears after a user clicks on the extension’s icon in the Chrome toolbar.
The popup.js file is a JavaScript file that is executed when the extension’s popup window is opened. It allows developers to add functionality and interactivity to the popup window. This file serves various purposes, including:
- Listen for events.
- Update the content of the popup window.
In addition to the CSS and JavaScript files, the popup.html file:
- Determines what information is displayed to the user.
- Provides user controls and interactive elements.
- Allows for the execution of JavaScript code within the popup window.
It serves as the foundation for constructing the visual layout and structure of the window, enabling developers to present relevant information, interactive features, and a user-friendly interface to enhance the extension’s functionality and usability.
options Files
The options.css file is a CSS file that defines the style of the extension’s options page. It determines how the options page appears visually to the user. When the user clicks on the extension’s icon in the Chrome toolbar and selects “Options,” a small window, known as the options page, appears. This page allows users to configure the settings of the extension according to their preferences.
The options.js file, on the other hand, is a JavaScript file that executes when the extension’s options page is opened. It provides the functionality for the options page and allows developers to implement various actions and behaviours. Some of the tasks that can be performed using options.js include:
- Event listening.
- Updating the content of the options page dynamically.
The options.html file is an HTML file that defines the content of the extension’s options page. It serves as the structure and layout of the page, providing the foundation for the visual elements and user interface components. By modifying the options.html file, developers can design and organize the content of the options page, enabling users to conveniently customize the settings of the extension to their liking.
Icon Files
The icons files define the icons for your extension. The icons files must be located in the extension’s root directory.
It is important to note that not all the files Iβve described will be used for every extension. Rather, based on the requirements and design you have in mind for your extension, you will only be using a few selected files.
Step 1: Set Up the Development Environment
In order to setup our development environment, we first must identify what files our extension will need in order to work the way we want it to. For example, based on my description of the URL Saver extension and the functions of the files I have described, we can see that we will need the following files:
- manifest.json
- content-script.js
- popup.css
- popup.js
- popup.html
- Icon files
Now that we know what files we need, we can begin setting up our development environment by following the steps below:
- Open a text editor of your choosing.
- Create a folder named after the extension you want to create.
- In the folder, create and name appropriately the files you will need to build your extension.
Step 2: Add in the Code
Now that our development environments are properly setup, we need to prompt ChatGPT to write the code for us. We will need to send a prompt to ChatGPT that includes an appropriate mix of the following:
- Detailed description of our extension.
- Name of the file we want written.
- Specific instructions of what we want written in the file.
- Request to begin writing the code for each file.
Once the code has been printed, you need to copy and paste it into the appropriate files.
I will also be providing all the prompts I used to get ChatGPT to print the code for each file in the βURL Saverβ extension. Itβs important to note that even if you use the exact same prompts I will provide below, there is a chance ChatGPT will produce code with slight deviations from the one it provided me. If the deviations affect the functionality of the end product in any way, all you have to do is ask ChatGPT to make the appropriate changes you want and reprint the code. Alternatively you can also try regenerating the response until ChatGPT gives you the exact code you want.
- Here is the prompt I used to get the manifest.json file:
βCreate a manifest file for a Chrome extension called “URL Saver” with the following specifications:
- Set the manifest version to 2.
- Name the extension “URL Saver.”
- Assign it the version “1.0.”
- Provide a description: “Save and manage website URLs.”
- Define icons for various sizes (16×16, 32×32, 48×48, and 128×128) with corresponding image files: “icon16.png,” “icon32.png,” “icon48.png,” and “icon128.png.”
- Specify the necessary permissions: “tabs” and “storage.”
- Configure a browser action with a default popup HTML file named “popup.html” and an icon file named “icon.png.”
- Include a content script that matches all URLs (“<all_urls>”) and use the script file “content-script.js.”
- Make “popup.css” a web-accessible resource available for all URLs (“<all_urls>”).
Please generate the manifest.json file based on these requirements.β
- The manifest.json file that printed:
{
"manifest_version": 2,
"name": "URL Saver",
"version": "1.0",
"description": "Save and manage website URLs",
"icons": {
"16": "icon16.png",
"32": "icon32.png",
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"tabs",
"storage"
],
"browser_action": {
"default_popup": "popup.html",
"default_icon": "icon16.png"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content-script.js"]
}],
"web_accessible_resources": [
{
"resources": ["popup.css"],
"matches": ["<all_urls>"]
}
]
}
For the URL Saver extension, the above code specifies the:
- Version.
- Name.
- Description.
- Icons.
It also declares the required permissions, including access to tabs and storage APIs. The browser action section determines the default popup HTML file and icon for the extension’s toolbar button. The manifest includes a content script that will be injected into all web pages.
- Here is the following prompt I used to get the content-script.js file:
βCreate a content script for the “URL Saver” Chrome extension. The content script should have the following functionality:
- Listen for changes in the URL of the currently active tab.
- When the URL changes, send a message to the extension background script with the updated URL.
- The content script should be triggered by the chrome.tabs.onUpdated event.
- The content script should only send a message when the changeInfo object contains a valid URL (i.e., when changeInfo.url is present).
- Use the chrome.runtime.sendMessage method to send the message to the extension background script.
- Ensure that the code is encapsulated within a JavaScript function or block as necessary.
Please provide the JavaScript code that accomplishes the above tasks.β
- The content-script.js file that printed:
// Listen for changes in the URL and send a message to the extension
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.url) {
chrome.runtime.sendMessage({ url: changeInfo.url });
}
});
The above code listens for changes in the URL of the active tab. When a URL update occurs, the chrome.tabs.onUpdated
event listener is triggered. It checks if the changeInfo.url
property exists, indicating that the URL has changed. If so, it sends a message to the extension using chrome.runtime.sendMessage()
, passing the updated URL as the payload. This allows the extension to receive and handle the URL updates from the content script.
Please also note that I have intentionally left a bug in the content-script.js code above as an exercise for you to try debugging files using ChatGPT in Step 5 of this tutorial. You will find the following error in the above code: TypeError: Cannot read properties of undefined (reading βonUpdatedβ)
- Here is the following prompt I used to get the popup.css file:
βPlease create a CSS code snippet for a Chrome extension popup with the following styles:
- Set the width of the body element to 300px.
- Center-align the text in the h1 element.
- Style the ul element to have no bullet points and zero padding.
- For each li element within the ul, do the following:
- Add a margin of 10px to the bottom.
- Make them display as flex containers.
- Align the items within each li element to the center.
- Style elements with the class .delete-button to have the following properties:
- Text color: red.
- Cursor: pointer.
- Margin to the left: 5px.
Please ensure that the generated CSS adheres to these specifications for a Chrome extension popup.β
- The popup.css file that printed:
body {
width: 300px;
}
h1 {
text-align: center;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin-bottom: 10px;
display: flex;
align-items: center;
}
.delete-button {
color: red;
cursor: pointer;
margin-left: 5px;
}
The provided CSS code defines the styling for the extension’s popup window. It ensures a visually pleasing and well-organized appearance for the popup window of the extension.
- Here is the following prompt I used to get the popup.js file:
βI want to create a Chrome extension named “URL Saver” with the following features:
- Users can save the URL of the website they are currently on.
- Users can add a title for every URL they want to save.
- Users can view a list of all the saved URLs by clicking on the extension icon in the popup.
- The extension should allow users to save a maximum of 20 URLs. When the limit is reached, the oldest URL should be removed to make space for the new one.
- Users should be able to delete any URL from the list by clicking on a cross (X) icon that appears next to each item.
Please provide the JavaScript code for the popup.js
file that implements these features. The code should include the following functions:
- A function named
deleteURL(index)
that deletes a URL from storage and updates the list in the popup when given an index. It should use the Chrome storage API. - A function named
displayURLs(urls)
that displays the saved URLs in the popup. It should take an array of URL objects as input and render them in an HTML list. Each list item should include the URL’s title, a clickable link to the URL, and a delete button. - Retrieve the saved URLs from storage when the popup is opened and display them using the
displayURLs
function. - Listen for a click event on a “Save” button in the popup. When clicked, it should save the current URL and a user-provided title using the Chrome storage API. If the limit of 20 URLs is reached, the oldest URL should be removed. After saving, the list of URLs should be updated.
Please ensure that the code is structured and commented for clarity. Thank you!β
- The popup.js file that printed:
// Function to delete a URL from storage and update the list in the popup
function deleteURL(index) {
chrome.storage.local.get('urls', function(result) {
let urls = result.urls || [];
urls.splice(index, 1);
chrome.storage.local.set({ urls: urls }, function() {
// Update the displayed list
displayURLs(urls);
});
});
}
// Function to display the URLs in the popup
function displayURLs(urls) {
const urlList = document.getElementById('urlList');
urlList.innerHTML = '';
urls.forEach(function(urlObj, index) {
const listItem = document.createElement('li');
const title = document.createElement('strong');
const link = document.createElement('a');
const deleteButton = document.createElement('span');
title.textContent = urlObj.title;
link.href = urlObj.url;
link.target = '_blank';
link.textContent = urlObj.url;
deleteButton.className = 'delete-button';
deleteButton.textContent = 'X';
deleteButton.addEventListener('click', function() {
deleteURL(index);
});
listItem.appendChild(title);
listItem.appendChild(document.createElement('br'));
listItem.appendChild(link);
listItem.appendChild(deleteButton);
urlList.appendChild(listItem);
});
}
// Retrieve the saved URLs from storage and display them in the popup
chrome.storage.local.get('urls', function(result) {
const urls = result.urls || [];
displayURLs(urls);
});
// Listen for a click event on the save button and save the current URL
document.getElementById('saveButton').addEventListener('click', function() {
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
const currentTab = tabs[0];
const url = currentTab.url;
const title = prompt('Enter a title for the URL:', currentTab.title);
if (url && title) {
chrome.storage.local.get('urls', function(result) {
let urls = result.urls || [];
if (urls.length >= 20) {
urls.shift(); // Remove the oldest URL if the limit is reached
}
urls.push({ title: title, url: url });
chrome.storage.local.set({ urls: urls }, function() {
// Update the displayed list
displayURLs(urls);
});
});
}
});
});
The above code handles the functionality of saving, deleting, and displaying URLs in the extension’s popup. It includes functions for deleting a URL from storage and updating the displayed list, as well as displaying the URLs in the popup with clickable links and delete buttons. The saved URLs are retrieved from storage and displayed when the popup is opened. Additionally, a click event listener is added to the save button, allowing the user to save the current URL with a custom title. The code ensures that the maximum limit of 20 URLs is maintained by removing the oldest URL if necessary.
- Here is the following prompt I used to get the popup.html file:
βPlease generate an HTML file named “popup.html” for a Chrome extension called “URL Saver.” The extension should have the following features:
- Allow users to save the URL of the website they’re currently on.
- Provide an input field for users to add a title for the URL they want to save.
- Display a list of all saved URLs.
- Limit the maximum number of saved URLs to 20.
- Allow users to delete any URL from the list by clicking on a cross that appears next to each item.β
- The popup.html file that printed:
<!DOCTYPE html>
<html>
<head>
<title>URL Saver</title>
</head>
<body>
<h1>URL Saver</h1>
<div id="urlContainer">
<ul id="urlList"></ul>
<div id="buttonContainer">
<button id="saveButton">Save URL</button>
</div>
</div>
<script src="popup.js"></script>
</body>
</html>
The provided HTML code represents the structure of the extension’s popup window. The HTML file also includes a reference to the popup.js
JavaScript file for handling the interactivity and functionality of the popup window.
Step 3: Switch from Manifest Version 2 to Manifest Version 3
Looking at the code that was generated for the URL Saver extension, you may have noticed that ChatGPT wrote the manifest.json file in Manifest Version 2. This is because the ChatGPTβs training data is cut off at 2021 and it does not know that Google will stop supporting extensions using Manifest Version 2 from 1 June 2023. When I have asked ChatGPT to code extensions in Manifest Version 3, it consistently produced code with bugs. Therefore, it is easier to have ChatGPT write the code in Version 2 and migrate it ourselves.
The reason why one of the pre-requisites for this article was to familiarize yourself with Googleβs documentation on how to migrate from Version 2 to 3, is because every extension is unique, so the modifications that will need to be done to the code during the migration will differ. Once you read through the documentation, you will be equipped with the knowledge to migrate any extension you create with ChatGPT to Version 3.
To migrate the URL Saver extension over to Version 3, I only had to update the manifest.json file. I changed "manifest_version": 2
to "manifest_version": 3
and I replaced the browser_action
key with the action
key. These changes align with the updated Manifest Version 3 syntax, explained by Google in their documentation. Below you can see an updated version of the manifest.json file for the URL Saver extension.
{
"manifest_version": 3,
"name": "URL Saver",
"version": "1.0",
"description": "Save and manage website URLs",
"icons": {
"16": "icon16.png",
"32": "icon32.png",
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"tabs",
"storage"
],
"action": {
"default_popup": "popup.html",
"default_icon": "icon16.png"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content-script.js"]
}],
"web_accessible_resources": [
{
"resources": ["popup.css"],
"matches": ["<all_urls>"]
}
]
}
Step 4: Add in the Icon Files
Finally, you will need to add four PNG icons to your projects root directory:
- icon16.png: This icon is used in the Chrome toolbar.
- icon32.png: This icon is used in the Chrome extensions management page.
- icon48.png: This icon is used in the Chrome extensions options page.
- icon128.png: This icon is used in the Chrome Web Store.
Here are links to 4 icons you can consider using in this project:
Remember to name the icons you add to the root directory appropriately, as described above.
Step 5: Test and Debug the Chrome Extension with ChatGPT
Now that your extension is complete, you will need to test it. In order to do that you will need to:
- Ensure βDeveloper Modeβ is enabled at upper right.
- Open Chrome and go to chrome://extensions.
- Click on the Load unpacked extension button.
- Select the folder containing your extension’s files.
- Test the extensions functionality on different websites.
- Check for errors. As you test the extension, pay attention to any errors that may occur. These errors could be caused by a problem with your code or with the website you are testing on.
If you find any bugs in your code or your extension is not working as intended, you should:
- Identify the file or files where the problem lies.
- Paste the code of the file into ChatGPT.
- Describe the problem you are facing in detail.
- Prompt ChatGPT to modify the code to fix the problem.
Step 6: Publish the Chrome Extension
Now that you have a working Chrome extension, you can follow the steps below if you wish to publish it to the Chrome Web Store:
- Create a developer account. You need to create a Google Developer account in order to publish a Chrome extension. The cost of a developer account is $5 per year.
- Package your extension. Once you have created your manifest file, you need to package your extension into a ZIP file. You can do this using a ZIP compression tool, such as 7-Zip or WinRAR.
- Upload your extension to the Chrome Web Store. Once you have packaged your extension, you can upload it to the Chrome Web Store. To do this, go to the Chrome Web Store Developer Dashboard and click the “Add New Item” button. Then, select “Extension” from the list of item types and click the “Create” button. Follow the instructions on the screen to upload your extension.
- Submit your extension for review. Once you have uploaded your extension, it will be reviewed by Google. This process can take a few days. Once your extension has been approved, it will be published in the Chrome Web Store.
Conclusion
In conclusion, building a Chrome extension with the help of ChatGPT can greatly simplify the development process. By understanding the architecture, setting up the environment, adding the code, transitioning to manifest version 3, incorporating icon files, conducting thorough testing, and publishing the extension, you can successfully create and share your own Chrome extension with the world.