Chrome extension Costco deal trackers represent a practical category of shopping automation tools that help users monitor price changes, detect deals, and get notified when items drop to target prices. For developers and power users, building your own Costco deal tracker extension provides full control over notification preferences, tracking logic, and data storage without relying on third-party services.
Understanding Costco Deal Tracking Challenges
Costco’s website presents specific challenges for deal tracking. Unlike Amazon or Walmart, Costco doesn’t provide a public API for price data. The site uses dynamic content loading, and product pages contain pricing information that changes based on membership tier, location, and inventory status. This means your extension needs to handle JavaScript-rendered content and parse pricing from the page itself.
Additionally, Costco products often have multiple price points: the current price, the member price, and potential instant rebates. A robust tracker must capture all these variations and correctly identify which represents the best deal.
Extension Architecture
A functional Costco deal tracker extension consists of several components working together. The background script handles scheduled polling and notifications, the content script extracts product data from pages, and the popup provides a user interface for managing tracked items.
Here’s the manifest configuration for Manifest V3:
// manifest.json
{
"manifest_version": 3,
"name": "Costco Deal Tracker",
"version": "1.0",
"description": "Track Costco deals and price drops",
"permissions": ["activeTab", "storage", "notifications", "scripting"],
"host_permissions": ["*://*.costco.com/*"],
"action": {
"default_popup": "popup.html",
"default_icon": "icon.png"
},
"background": {
"service_worker": "background.js"
}
}
The extension requests activeTab permission to read page content when you’re viewing a product, storage permission to save tracked items locally, and notifications to alert you of price drops.
Extracting Product Data
The content script runs on Costco product pages and extracts relevant pricing information. Here’s a practical implementation:
// content.js
function extractProductData() {
const product = {};
// Extract product title
const titleElement = document.querySelector('h1.product-title');
product.title = titleElement ? titleElement.textContent.trim() : null;
// Extract primary price
const priceElement = document.querySelector('.value[data-testid="price"]');
product.price = priceElement ? parseFloat(priceElement.textContent.replace(/[^0-9.]/g, '')) : null;
// Extract member price if available
const memberPriceElement = document.querySelector('.member-price .value');
product.memberPrice = memberPriceElement ? parseFloat(memberPriceElement.textContent.replace(/[^0-9.]/g, '')) : null;
// Extract product SKU/ID from URL
const urlMatch = window.location.pathname.match(/item\.(\d+)/);
product.sku = urlMatch ? urlMatch[1] : null;
// Get full URL for tracking
product.url = window.location.href;
// Timestamp for price history
product.timestamp = new Date().toISOString();
return product;
}
// Listen for messages from popup or background
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === 'getProductData') {
const data = extractProductData();
sendResponse(data);
}
});
This script parses the page DOM to extract pricing. Note that Costco’s site structure may change, so you should test selectors against actual product pages and consider using more robust selector strategies for production.
Managing Tracked Items
Store tracked items using Chrome’s storage API. Each tracked item should include the product URL, target price, and price history:
// background.js - Managing tracked items
async function addTrackItem(productData, targetPrice) {
const item = {
sku: productData.sku,
title: productData.title,
url: productData.url,
targetPrice: targetPrice,
currentPrice: productData.price || productData.memberPrice,
priceHistory: [{
price: productData.price || productData.memberPrice,
timestamp: productData.timestamp
}],
lastChecked: new Date().toISOString()
};
const { trackedItems = {} } = await chrome.storage.local.get('trackedItems');
trackedItems[productData.sku] = item;
await chrome.storage.local.set({ trackedItems });
return item;
}
The price history array enables you to show users price trends over time, which is valuable for determining whether a current price represents a genuine deal.
Implementing Price Checking
Background scripts can run periodically to check prices on tracked items. However, directly scraping Costco from a background script often fails due to anti-bot measures. A more reliable approach uses the activeTab permission to trigger checks when the user visits a product page:
// background.js - Checking prices on page visit
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete' && tab.url?.includes('costco.com')) {
// Check if this is a product page
if (tab.url.includes('/item.')) {
const response = await chrome.tabs.sendMessage(tabId, { action: 'getProductData' });
if (response?.sku) {
await checkAndUpdatePrice(response);
}
}
}
});
async function checkAndUpdatePrice(productData) {
const { trackedItems = {} } = await chrome.storage.local.get('trackedItems');
const item = trackedItems[productData.sku];
if (!item) return;
const currentPrice = productData.price || productData.memberPrice;
// Update price history
item.priceHistory.push({
price: currentPrice,
timestamp: productData.timestamp
});
// Keep only last 30 price points
if (item.priceHistory.length > 30) {
item.priceHistory = item.priceHistory.slice(-30);
}
item.lastChecked = new Date().toISOString();
item.currentPrice = currentPrice;
// Check if price dropped below target
if (currentPrice <= item.targetPrice && currentPrice < item.priceHistory[0].price) {
sendNotification(item, currentPrice);
}
trackedItems[productData.sku] = item;
await chrome.storage.local.set({ trackedItems });
}
function sendNotification(item, newPrice) {
chrome.notifications.create({
type: 'basic',
iconUrl: 'icon.png',
title: 'Costco Deal Alert!',
message: `${item.title} is now $${newPrice} (target: $${item.targetPrice})`
});
}
This approach checks prices whenever you visit a tracked product page, avoiding the need for background polling that might trigger rate limiting.
Handling Multiple Price Points
Costco products frequently display multiple prices. Your extension should track the lowest available price and notify users accordingly:
function getBestPrice(productData) {
const prices = [];
if (productData.price) prices.push(productData.price);
if (productData.memberPrice) prices.push(productData.memberPrice);
// Also check for instant rebates in the DOM
const rebateElement = document.querySelector('.instant-rebate .value');
if (rebateElement) {
const rebate = parseFloat(rebateElement.textContent.replace(/[^0-9.]/g, ''));
if (productData.price) prices.push(productData.price - rebate);
}
return prices.length > 0 ? Math.min(...prices) : null;
}
Building the Popup Interface
The popup provides users with a simple interface to view and manage tracked items:
<!-- popup.html -->
<!DOCTYPE html>
<html>
<head>
<style>
body { width: 320px; font-family: system-ui, sans-serif; }
.item { padding: 12px; border-bottom: 1px solid #eee; }
.item-title { font-weight: 600; font-size: 14px; }
.price-info { margin-top: 4px; font-size: 13px; }
.current { color: #0070c9; }
.target { color: #107c10; }
.remove-btn {
background: #d32f2f; color: white;
border: none; padding: 4px 8px;
cursor: pointer; font-size: 12px;
}
</style>
</head>
<body>
<h3>Tracked Items</h3>
<div id="tracked-list"></div>
<script src="popup.js"></script>
</body>
</html>
// popup.js
async function loadTrackedItems() {
const { trackedItems = {} } = await chrome.storage.local.get('trackedItems');
const list = document.getElementById('tracked-list');
Object.values(trackedItems).forEach(item => {
const div = document.createElement('div');
div.className = 'item';
div.innerHTML = `
<div class="item-title">${item.title}</div>
<div class="price-info">
<span class="current">$${item.currentPrice}</span> →
<span class="target">$${item.targetPrice}</span>
</div>
<button class="remove-btn" data-sku="${item.sku}">Remove</button>
`;
list.appendChild(div);
});
document.querySelectorAll('.remove-btn').forEach(btn => {
btn.addEventListener('click', async (e) => {
const sku = e.target.dataset.sku;
delete trackedItems[sku];
await chrome.storage.local.set({ trackedItems });
location.reload();
});
});
}
loadTrackedItems();
Practical Considerations
When deploying your Costco deal tracker, consider these practical aspects. First, Costco’s page structure changes periodically, so build in selector flexibility and include error handling for missing elements. Second, respect rate limits by not checking prices too frequently. The approach shown here—checking when users visit pages—is both efficient and respectful. Third, consider adding local storage encryption for sensitive data if you expand beyond simple price tracking.
For developers looking to extend this functionality, adding price history visualization, CSV export for price data, or integration with external notification services like Pushover or Discord webhooks provides additional value without significant complexity.
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