Claude Skills Guide

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.

Built by theluckystrike — More at zovo.one