Hostname, structured product price, and only enough retailer markup to locate that price.
Free browser tool · no account · no extension
Drag one button. Price the exit before buying the bike.
Regret Lens recognizes nine supported direct-order stores, reads the structured product price on your device, and opens Skinflint's maintained return-cost answer. It does not send the retailer page or price in the web request.
Desktop install
Drag this button to the bookmarks bar.
Do not click to install. Drag it into the bookmarks or favorites bar, then click it while viewing a supported e-bike product.
Price the exitOn a managed browser or mobile device that blocks bookmarklets, use the ordinary Skinflint calculator.
- 1 · Keep shopping normally.Open the exact product page before checkout.
- 2 · Click Price the exit.The code looks only for the store host and structured product price.
- 3 · Read the receipt.Skinflint opens with the maintained policy, deduction, refund range, and first-party source.
The anti-extension
No mystery permissions. The complete code is inspectable.
Retailer URL, page contents, cart, account, browsing history, or price in the HTTP request.
Skinflint with generic bookmarklet attribution; brand and price remain in the URL fragment.
Audit the complete bookmarklet source
(function regretLensRuntime(rules, homeUrl) {
"use strict";
function normalizedHost(value) {
return String(value || "").trim().toLowerCase().replace(/^www\./, "").replace(/\.$/, "");
}
function brandForHost(hostname) {
const host = normalizedHost(hostname);
const match = rules.find((candidate) => candidate.hosts.some((configuredHost) => {
const configured = normalizedHost(configuredHost);
return candidate.exactHost ? host === configured : host === configured || host.endsWith(`.${configured}`);
}));
if (match) return match.brandId;
const destinationHost = normalizedHost(new URL(homeUrl).hostname);
if ((destinationHost === "localhost" || destinationHost === "127.0.0.1") && host.endsWith(".localhost")) {
const localBrand = host.slice(0, -".localhost".length);
return rules.some((candidate) => candidate.brandId === localBrand) ? localBrand : "";
}
return "";
}
function priceNumber(value) {
const normalized = String(value == null ? "" : value).replaceAll(",", "").match(/(?:USD\s*)?\$?\s*(\d+(?:\.\d{1,2})?)/i);
if (!normalized) return null;
const amount = Number(normalized[1]);
return Number.isFinite(amount) && amount >= 200 && amount <= 15000 ? Math.round(amount) : null;
}
function offerPrice(offer) {
if (!offer || typeof offer !== "object") return null;
if (Array.isArray(offer)) {
for (const item of offer) {
const found = offerPrice(item);
if (found) return found;
}
return null;
}
return priceNumber(offer.price ?? offer.lowPrice ?? offer.highPrice ?? offer.priceSpecification?.price);
}
function productPrice(value) {
if (!value || typeof value !== "object") return null;
if (Array.isArray(value)) {
for (const item of value) {
const found = productPrice(item);
if (found) return found;
}
return null;
}
const types = Array.isArray(value["@type"]) ? value["@type"] : [value["@type"]];
if (types.includes("Product")) {
const found = offerPrice(value.offers);
if (found) return found;
}
if (value["@graph"]) return productPrice(value["@graph"]);
return null;
}
function structuredPrice() {
const metaSelectors = [
'meta[property="product:price:amount"]',
'meta[property="og:price:amount"]',
'meta[name="product:price:amount"]',
'[itemprop="price"][content]',
'meta[itemprop="price"]'
];
for (const selector of metaSelectors) {
const element = document.querySelector(selector);
const found = priceNumber(element?.getAttribute("content") || element?.getAttribute("value"));
if (found) return found;
}
for (const script of Array.from(document.querySelectorAll('script[type="application/ld+json"]')).slice(0, 20)) {
try {
const found = productPrice(JSON.parse(script.textContent || "null"));
if (found) return found;
} catch {
// Ignore invalid retailer markup and fall back to a visible price field or prompt.
}
}
const itemprop = document.querySelector('[itemprop="price"]');
return priceNumber(itemprop?.textContent);
}
const brandId = brandForHost(location.hostname);
let price = structuredPrice();
if (!price) {
const entered = prompt("Regret Lens could not reliably find the full bike price. Enter the purchase price in USD, or leave blank to choose it on Skinflint:", "");
price = priceNumber(entered);
}
const target = new URL(homeUrl);
target.searchParams.set("utm_source", "bookmarklet");
target.searchParams.set("utm_medium", "tool");
target.searchParams.set("utm_campaign", "regret_lens");
target.searchParams.set("utm_content", brandId ? "supported-store" : "unsupported-store");
const privateState = new URLSearchParams({ condition: "ridden" });
if (brandId) privateState.set("brand", brandId);
if (price) privateState.set("price", String(price));
target.hash = `calculator?${privateState.toString()}`;
const opened = window.open(target.toString(), "_blank", "noopener,noreferrer");
if (opened) opened.opener = null;
else location.assign(target.toString());
})([{"brandId":"lectric","hosts":["lectricebikes.com"]},{"brandId":"aventon","hosts":["aventon.com","rideaventon.com"]},{"brandId":"velotric","hosts":["velotricbike.com"]},{"brandId":"rad-power-bikes","hosts":["radpowerbikes.com"]},{"brandId":"ride1up-revv1","hosts":["revv1.ride1up.com"],"exactHost":true},{"brandId":"fiido","hosts":["fiido.com"]},{"brandId":"himiway","hosts":["himiwaybike.com"]},{"brandId":"hovsco","hosts":["hovsco.com"]},{"brandId":"ecotric","hosts":["ecotric.com"]}],"https://skinflint.ai/");Launch coverage · source checked July 19, 2026
Nine supported policy scopes.
- Lectriclectricebikes.com
- Aventonaventon.com, rideaventon.com
- Velotricvelotricbike.com
- Rad Power Bikesradpowerbikes.com
- Ride1Up Revv 1revv1.ride1up.com
- Fiidofiido.com
- Himiwayhimiwaybike.com
- HOVSCOhovsco.com
- Ecotricecotric.com
Ride1Up coverage is limited to the indexed Revv 1 policy host. Dealer, marketplace, and unsupported model pages remain manual rather than being mapped to the wrong terms.
Regret Lens, answered.
What is the Regret Lens e-bike bookmarklet?
Regret Lens is a free bookmarklet that recognizes a supported e-bike store, reads a structured product price locally when available, and opens Skinflint's source-dated return-cost calculator with the brand and price prefilled.
Does Regret Lens send the retailer page or bike price to Skinflint?
No. The bookmarklet makes no network request and opens Skinflint with brand and price in the URL fragment, which browsers do not send in the HTTP request. Skinflint receives ordinary hosting metadata and generic bookmarklet campaign labels after the user chooses to open it.
What if Regret Lens cannot detect the price or store?
It asks for the price locally when structured product markup is missing. An unsupported store opens the calculator without selecting a brand so the shopper can choose manually.
Is a bookmarklet a browser extension?
No. A bookmarklet is a saved browser bookmark containing visible JavaScript. Regret Lens installs no extension, requests no account, and injects no remote code into the retailer page.
Before fulfillment advances or the bike leaves your possession
Turn the current policy into a written seller request.
The $12 kit builds an editable seller-specific cancellation or return request, private refund downside file, route-specific evidence checklist, source receipt, and applicable deadline calendar, plus a manually verified 30-day weekly source watch for one indexed brand.