Building a Chrome Extension for Best Buy Price Alerts
Price tracking extensions have become essential tools for savvy shoppers and developers interested in browser automation. If you want to monitor product prices on Best Buy and receive notifications when prices drop, building a custom Chrome extension gives you full control over the tracking logic and notification system. This guide walks you through creating a functional price alert extension tailored for Best Buy, with practical code examples you can adapt for your own projects.
Understanding the Extension Architecture
A Chrome extension for price monitoring consists of three core components: the manifest file that declares permissions and capabilities, a background service worker for handling periodic checks, and a content script or popup interface for user interaction. For Best Buy price alerts, you’ll need to fetch product pages, parse the price data, and trigger browser notifications when prices fall below your target threshold.
Before starting, ensure you have Chrome or a Chromium-based browser for testing. You’ll also need a basic text editor or IDE for writing JavaScript and JSON files.
Creating the Manifest File
Every Chrome extension begins with a manifest.json file that defines the extension’s identity and permissions. For a price alert extension targeting Best Buy, you’ll need permissions for storage (to save user preferences), notifications (to alert users), and optionally activeTab for reading page content.
{
"manifest_version": 3,
"name": "Best Buy Price Alert",
"version": "1.0",
"description": "Monitor Best Buy prices and get notified when they drop",
"permissions": [
"storage",
"notifications",
"activeTab"
],
"host_permissions": [
"https://www.bestbuy.com/*"
],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"background": {
"service_worker": "background.js"
}
}
Save this file as manifest.json in your extension directory. The host permissions specify that your extension can access Best Buy product pages, which is necessary for fetching price data.
Building the Popup Interface
The popup provides the user interface where users add products to track and set their desired price thresholds. Create a simple HTML file with input fields for the product URL and target price.
<!DOCTYPE html>
<html>
<head>
<style>
body { width: 320px; padding: 16px; font-family: system-ui, sans-serif; }
input { width: 100%; padding: 8px; margin: 8px 0; box-sizing: border-box; }
button { width: 100%; padding: 10px; background: #0046be; color: white; border: none; cursor: pointer; }
button:hover { background: #003687; }
.product-list { margin-top: 16px; }
.product-item { padding: 8px; border-bottom: 1px solid #eee; font-size: 13px; }
.remove-btn { color: red; cursor: pointer; float: right; }
</style>
</head>
<body>
<h3>Best Buy Price Alert</h3>
<input type="text" id="productUrl" placeholder="Best Buy product URL">
<input type="number" id="targetPrice" placeholder="Target price ($)">
<button id="addProduct">Add to Watch List</button>
<div id="productList" class="product-list"></div>
<script src="popup.js"></script>
</body>
</html>
The popup stores tracked products in Chrome’s storage API, making the data persistent across browser sessions.
Implementing the Popup Logic
The popup JavaScript handles adding products to the watch list and displaying currently tracked items. This script manages the interaction between the user interface and Chrome’s storage system.
document.addEventListener('DOMContentLoaded', () => {
loadProducts();
document.getElementById('addProduct').addEventListener('click', addProduct);
});
function loadProducts() {
chrome.storage.local.get(['watchList'], (result) => {
const products = result.watchList || [];
const list = document.getElementById('productList');
list.innerHTML = products.map((p, index) => `
<div class="product-item">
<span>$${p.targetPrice} - ${p.url.substring(0, 40)}...</span>
<span class="remove-btn" data-index="${index}">×</span>
</div>
`).join('');
document.querySelectorAll('.remove-btn').forEach(btn => {
btn.addEventListener('click', (e) => removeProduct(e.target.dataset.index));
});
});
}
function addProduct() {
const url = document.getElementById('productUrl').value;
const targetPrice = parseFloat(document.getElementById('targetPrice').value);
if (!url || !targetPrice) {
alert('Please enter both URL and target price');
return;
}
chrome.storage.local.get(['watchList'], (result) => {
const products = result.watchList || [];
products.push({ url, targetPrice, addedAt: Date.now() });
chrome.storage.local.set({ watchList: products }, () => {
loadProducts();
document.getElementById('productUrl').value = '';
document.getElementById('targetPrice').value = '';
});
});
}
function removeProduct(index) {
chrome.storage.local.get(['watchList'], (result) => {
const products = result.watchList || [];
products.splice(index, 1);
chrome.storage.local.set({ watchList: products }, loadProducts);
});
}
Creating the Background Service Worker
The background service worker runs continuously and periodically checks prices for all tracked products. This is where the core price monitoring logic lives.
chrome.alarms.create('priceCheck', { periodInMinutes: 60 });
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === 'priceCheck') {
checkAllPrices();
}
});
async function checkAllPrices() {
const { watchList } = await chrome.storage.local.get('watchList');
if (!watchList || watchList.length === 0) return;
for (const product of watchList) {
try {
const currentPrice = await fetchBestBuyPrice(product.url);
if (currentPrice && currentPrice <= product.targetPrice) {
sendNotification(product.url, currentPrice, product.targetPrice);
}
} catch (error) {
console.error('Error checking price:', error);
}
}
}
async function fetchBestBuyPrice(url) {
// Using a CORS proxy or Best Buy API recommended for production
const response = await fetch(url);
const html = await response.text();
// Extract price from Best Buy's page structure
const priceMatch = html.match(/"price":"(\d+\.?\d*)"/);
return priceMatch ? parseFloat(priceMatch[1]) : null;
}
function sendNotification(url, currentPrice, targetPrice) {
chrome.notifications.create({
type: 'basic',
iconUrl: 'icons/icon128.png',
title: 'Price Drop Alert!',
message: `Best Buy price: $${currentPrice} (target: $${targetPrice})`
});
}
Note that direct page fetching may encounter CORS restrictions. In a production extension, you’d typically use Best Buy’s API or a server-side proxy to retrieve price data reliably.
Loading and Testing Your Extension
To test your extension, open Chrome and navigate to chrome://extensions/. Enable Developer mode in the top right corner, then click Load unpacked and select your extension directory. The extension icon should appear in your toolbar.
Test the workflow by adding a Best Buy product URL and target price, then verify that the product appears in your watch list. The background worker will begin checking prices on the schedule you define.
Refinements and Production Considerations
For a production-ready extension, consider implementing exponential backoff for API calls to avoid rate limiting. Add error handling for products that become unavailable or out of stock. You might also want to store the last known price and only notify when there’s a meaningful change.
Adding a badge to the extension icon showing the number of price drops can improve user engagement. Using Chrome’s identity API to sync data across devices provides a more robust experience for users who switch between computers.
Building a Best Buy price alert extension gives you hands-on experience with Chrome extension APIs while creating a genuinely useful tool. The architecture shown here transfers directly to other retailers—simply adjust the price extraction regex and notification messages for Amazon, Newegg, or any other e-commerce site you want to monitor.
Related Reading
- Claude Code for Beginners: Complete Getting Started Guide
- Best Claude Skills for Developers in 2026
- Claude Skills Guides Hub
Built by theluckystrike — More at zovo.one