Building Kale: An Ethical Open-Source Alternative to Affiliate Hijacking
Overview
Modern browser extensions often use aggressive monetization tactics that undermine the very creators they sponsor.
Prerequisites
To follow this implementation, you should understand:
- JavaScript (ES6+): For extension logic and DOM manipulation.
- Browser APIs: Specifically
chrome.runtimeandchrome.cookies. - Python: For backend scraping and API management.
- Web Architecture: Understanding how cookies and HTTP redirects function.
Key Libraries & Tools
- Chrome Extension API: The core framework for browser interaction.
- Beautiful Soup: A Pythonlibrary for scraping coupons from external sites.
- Cloud Functions: Serverless components to handle periodic data scraping.

Code Walkthrough
The Manifest Foundation
The manifest.json file defines the extension's boundaries. You must explicitly request permissions to interact with sensitive user data.
{
"manifest_version": 3,
"permissions": ["storage", "tabs", "cookies", "activeTab"],
"host_permissions": ["https://*/*"]
}
Protecting Creator Commissions
The core of the "not-evil" philosophy is the isAffiliated function. It checks for existing cookies before the extension attempts to inject its own, preventing commission theft.
async function isAffiliated(domain, cookieName) {
const cookies = await chrome.cookies.getAll({ domain });
const found = cookies.filter(c => c.name === cookieName);
return found.length > 0;
}
Backend Automation
For the backend, we use
import requests
from bs4 import BeautifulSoup
def scrape_coupons(url):
res = requests.get(url)
soup = BeautifulSoup(res.text, 'html.parser')
# Logic to extract code strings
return [tag.text for tag in soup.find_all(class_='coupon-code')]
Syntax Notes
Browser extensions rely heavily on asynchronous patterns. Use async/await when calling chrome.cookies or chrome.tabs to avoid blocking the main UI thread. In the Python scraping logic, CSS selectors provide the most reliable way to target specific coupon containers on diverse e-commerce layouts.
Practical Examples
If a user visits
Tips & Gotchas
- Cross-Browser Compatibility: Chrome and Firefox use different API namespaces (
chromevsbrowser). Use a polyfill to maintain a single codebase. - DOM Injection: Websites frequently change their checkout page IDs. Implement robust error handling in
content.jsto ensure the popup doesn't break the user's checkout flow.