Sneaker Release Alert Chrome Extension (2026)
Sneaker release alerts have become essential tools for collectors, resellers, and enthusiasts who need real-time notifications when limited editions drop. Building a Chrome extension for sneaker release alerts requires understanding browser extension architecture, web scraping fundamentals, and notification systems. This guide walks through the technical implementation for developers and power users.
Core Architecture
A sneaker release alert Chrome extension operates through three primary components: a background service worker for continuous monitoring, content scripts for parsing retail sites, and a notification system for alerting users.
The extension architecture follows Chrome’s Manifest V3 specifications, which require asynchronous operations and use service workers instead of persistent background pages.
Manifest Configuration
Your extension begins with the manifest file that defines permissions and capabilities:
{
"manifest_version": 3,
"name": "Sneaker Release Alert",
"version": "1.0",
"description": "Monitor sneaker releases and send alerts",
"permissions": [
"storage",
"notifications",
"activeTab",
"scripting"
],
"host_permissions": [
"https://*.nike.com/*",
"https://*.adidas.com/*",
"https://*.stockx.com/*"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": "icon.png"
}
}
The host permissions array specifies which retail domains your extension can access for monitoring.
Implementing the Monitoring Service
The background service worker handles periodic checks against configured retailer endpoints. You need to implement rate limiting and respect each site’s terms of service.
// background.js - Core monitoring logic
const RETAILERS = [
{ name: 'Nike', url: 'https://www.nike.com/launch', selector: '.available-products' },
{ name: 'Adidas', url: 'https://www.adidas.com/us/release-dates', selector: '.product-card' },
{ name: 'StockX', url: 'https://stockx.com/latest/released', selector: '.product-grid' }
];
const CHECK_INTERVAL = 60000; // 1 minute
// Store tracked releases in chrome.storage
async function loadTrackedReleases() {
const result = await chrome.storage.local.get(['trackedReleases']);
return result.trackedReleases || [];
}
async function checkReleases() {
const tracked = await loadTrackedReleases();
for (const retailer of RETAILERS) {
try {
const releases = await fetchReleases(retailer);
const newReleases = findNewReleases(releases, tracked);
if (newReleases.length > 0) {
await sendNotifications(newReleases);
}
} catch (error) {
console.error(`Error checking ${retailer.name}:`, error);
}
}
}
async function fetchReleases(retailer) {
// Use Chrome's scripting API to execute in page context
const results = await chrome.scripting.executeScript({
target: { url: retailer.url },
func: (selector) => {
const elements = document.querySelectorAll(selector);
return Array.from(elements).map(el => ({
title: el.querySelector('.product-title')?.textContent,
price: el.querySelector('.price')?.textContent,
date: el.querySelector('.release-date')?.textContent,
url: el.querySelector('a')?.href
}));
},
args: [retailer.selector]
});
return results[0]?.result || [];
}
async function sendNotifications(releases) {
for (const release of releases) {
await chrome.notifications.create({
type: 'basic',
iconUrl: 'icon.png',
title: 'Sneaker Release Alert',
message: `${release.title} - ${release.price} Dropping: ${release.date}`
});
}
}
// Start periodic monitoring
setInterval(checkReleases, CHECK_INTERVAL);
User Interface Implementation
The popup interface allows users to configure their alert preferences and view tracked releases:
<!-- popup.html -->
<!DOCTYPE html>
<html>
<head>
<style>
body { width: 320px; padding: 16px; font-family: system-ui; }
.section { margin-bottom: 16px; }
label { display: block; margin-bottom: 8px; font-weight: 600; }
input[type="checkbox"] { margin-right: 8px; }
button {
background: #000; color: #fff; padding: 8px 16px;
border: none; border-radius: 4px; cursor: pointer;
}
#releases { max-height: 200px; overflow-y: auto; }
.release-item { padding: 8px; border-bottom: 1px solid #eee; }
</style>
</head>
<body>
<h2>Sneaker Alert Settings</h2>
<div class="section">
<label>Retailers to Monitor</label>
<div id="retailers"></div>
</div>
<div class="section">
<label>Notification Preferences</label>
<label><input type="checkbox" id="desktopNotify" checked> Desktop notifications</label>
<label><input type="checkbox" id="soundNotify" checked> Sound alerts</label>
</div>
<div class="section">
<button id="saveBtn">Save Settings</button>
</div>
<div class="section">
<h3>Tracked Releases</h3>
<div id="releases"></div>
</div>
<script src="popup.js"></script>
</body>
</html>
// popup.js
document.addEventListener('DOMContentLoaded', async () => {
// Load saved settings
const settings = await chrome.storage.local.get(['retailers', 'notifications']);
// Populate retailer checkboxes
const retailers = ['Nike', 'Adidas', 'StockX', 'Footlocker', 'FinishLine'];
const container = document.getElementById('retailers');
retailers.forEach(retailer => {
const label = document.createElement('label');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = settings.retailers?.includes(retailer) ?? true;
checkbox.value = retailer;
label.appendChild(checkbox);
label.appendChild(document.createTextNode(retailer));
container.appendChild(label);
});
// Handle save button
document.getElementById('saveBtn').addEventListener('click', async () => {
const selectedRetailers = Array.from(
document.querySelectorAll('#retailers input:checked')
).map(cb => cb.value);
await chrome.storage.local.set({
retailers: selectedRetailers,
notifications: {
desktop: document.getElementById('desktopNotify').checked,
sound: document.getElementById('soundNotify').checked
}
});
window.close();
});
});
Advanced Features
For production extensions, implement these advanced patterns:
Dynamic Refresh Rates: Adjust checking frequency based on known release calendars. Increase frequency during major drop events like Jordan releases or Yeezy drops.
Authentication Handling: Some retailers require login for release access. Implement OAuth flow within the extension using the identity API:
// Handle retailer authentication
async function authenticateRetailer(retailer) {
const authUrl = retailer.authEndpoint;
return new Promise((resolve, reject) => {
chrome.identity.launchWebAuthFlow(
{ url: authUrl, interactive: true },
(redirectUrl) => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
} else {
resolve(redirectUrl);
}
}
);
});
}
Data Persistence: Use IndexedDB for storing historical release data, enabling features like price tracking and release history:
import { openDB } from 'idb';
const dbPromise = openDB('sneaker-alerts-db', 1, {
upgrade(db) {
db.createObjectStore('releases', { keyPath: 'id' });
db.createObjectStore('alerts', { keyPath: 'id' });
}
});
async function saveRelease(release) {
const db = await dbPromise;
await db.put('releases', release);
}
async function getReleaseHistory(sneakerId) {
const db = await dbPromise;
return db.get('releases', sneakerId);
}
Deployment Considerations
When publishing to the Chrome Web Store, ensure your extension complies with store policies. Sneaker automation tools often face scrutiny, so frame your extension as a notification utility rather than an automated purchase tool.
Include clear privacy policies explaining data usage, implement proper CORS handling for cross-origin requests, and test thoroughly across different retailer site changes since these sites frequently update their DOM structures.
The implementation above provides a foundation that you can customize based on specific retailer targets and feature requirements. Focus on reliability and respect for retailer terms of service when building release monitoring tools.
Try it: Paste your error into our Error Diagnostic for an instant fix.
Related Reading
- Chrome Extension Travel Deal Alert: A Developer Guide
- AI Autocomplete Chrome Extension: A Developer’s Guide
- AI Bookmark Manager for Chrome: Organizing Your Web Knowledge
Built by theluckystrike. More at zovo.one
Step-by-Step: Setting Up Your First Alert
- Load the extension via
chrome://extensions> “Load unpacked” - Click the extension icon and check the retailers you want to monitor
- Enable desktop notifications when prompted
- Click “Save Settings”. the service worker starts checking on a 1-minute interval
- When a new release appears, a Chrome notification fires with name, price, and release date
- Click the notification to open the product page directly
Common Use Cases
Jordan Retro drops: Nike.com’s /launch URL surfaces upcoming releases before the SNKRS queue opens. Monitoring it provides advance visibility.
Yeezy restocks: Adidas restocks appear briefly before selling out. A 1-minute check interval often catches restock windows.
Footlocker exclusive colorways: Chain retailer exclusives often go live with minimal marketing. Monitoring multiple retailer domains catches drops that filter-based tools miss.
Comparison with Existing Alert Tools
| Tool | Retailers | Setup | Alert speed | Cost |
|---|---|---|---|---|
| This extension | Any (customizable) | Build yourself | Configurable | Free |
| Discord bots (Sole Alert) | Multi-retailer | Join Discord | Near-instant | Free/Paid |
| Eve from Snkrs | Nike only | Mobile app | Push notification | Free |
The extension is unique in that you control the check interval, selector logic, and notification format. Discord bots are faster for hyped releases but require community infrastructure you do not control.
Troubleshooting Common Issues
Selector no longer matching: Build fallback selectors and log misses for debugging:
async function fetchReleases(retailer) {
for (const selector of retailer.selectors) {
const elements = document.querySelectorAll(selector);
if (elements.length > 0) return Array.from(elements).map(el => parseRelease(el));
}
await chrome.storage.local.set({ lastMiss: { retailer: retailer.name, time: Date.now() } });
return [];
}
Service worker terminating between checks: Use the alarms API instead of setInterval. Alarms persist across service worker restarts in Manifest V3.
False positives from restocked items: Track seen products by ASIN or ID to avoid re-alerting on items already seen. Store seen IDs in chrome.storage.local.
Notifications not appearing: Add "notifications" to the manifest permissions array and prompt for permission on first run:
chrome.permissions.request({ permissions: ['notifications'] }, (granted) => {
if (!granted) alert('Enable notifications to receive sneaker alerts.');
});
When publishing to the Chrome Web Store, frame your extension as a notification utility rather than an automated purchase tool. the latter violates store policies and retailer terms. Include a clear privacy policy and test thoroughly across each target retailer.
Know your costs → Use our Claude Code Cost Calculator to estimate your monthly spend.