Every comparison site sits on structured data that other businesses would pay to use. We turned ours into embeddable widgets that brands put on their own sites — and it became our fastest-growing revenue channel.
Here's how we built it, priced it, and what we learned selling it.
The Problem We Solved
Brands have a comparison problem. Their customers are searching "Brand X vs Brand Y" before buying, but brands can't control that narrative on third-party sites. They either:
- Ignore comparison searches entirely (most common)
- Create biased comparison pages on their own site (low trust)
- Hope third-party comparison sites are favorable (no control)
Our widget gives them option 4: embed a neutral, data-backed comparison directly on their product pages. The data comes from our platform. The presentation matches their brand. The customer stays on their site.
Architecture: How the Widget Works
The embed is a lightweight JavaScript snippet that loads comparison data from our API:
<div id="smartreview-compare"
data-entity-a="airpods-pro-2"
data-entity-b="sony-wf-1000xm5"
data-theme="light"
data-brand-color="#1a73e8">
</div>
<script src="https://widgets.aversusb.net/compare.js" async></script>
The script does three things:
- Fetches comparison data from our CDN-cached API (avg 45ms response time)
- Renders a responsive comparison card using Shadow DOM (no CSS conflicts with host page)
- Tracks impressions and clicks for the brand's analytics dashboard
Why Shadow DOM Matters
Early versions used standard DOM injection. Every third brand had CSS conflicts — their reset stylesheets broke our layout, their font stacks overrode ours, their box-sizing rules shifted columns.
Shadow DOM encapsulates everything. The widget renders identically on a Shopify store, a WordPress blog, and a custom React app. Zero support tickets since we switched.
class CompareWidget extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
async connectedCallback() {
const entityA = this.dataset.entityA;
const entityB = this.dataset.entityB;
const theme = this.dataset.theme || 'light';
const brandColor = this.dataset.brandColor || '#2563eb';
const data = await fetch(
`https://api.aversusb.net/v1/compare/${entityA}/${entityB}`
).then(r => r.json());
this.shadowRoot.innerHTML = this.render(data, theme, brandColor);
this.trackImpression(entityA, entityB);
}
}
customElements.define('smartreview-compare', CompareWidget);
Performance Budget
The widget script is 8KB gzipped. We set this as a hard ceiling because every KB matters when you're asking brands to add third-party JavaScript to their product pages.
Breakdown:
- Core rendering: 3.2KB
- Data fetching + caching: 1.8KB
- Analytics tracking: 1.1KB
- Theme engine: 1.4KB
- Error handling + fallback: 0.5KB
No framework dependencies. No external CSS. No web fonts. Pure vanilla JS with a compile step that tree-shakes aggressively.
Theming System
Brands won't embed anything that looks out of place. Our theming system accepts:
- Brand color: Primary accent used for headers, highlights, CTAs
- Theme: Light or dark mode
- Layout: Horizontal (for product pages) or vertical (for sidebars)
- Attributes: Which comparison dimensions to show (up to 8)
- CTA: Custom button text and destination URL
The brand color propagates through the entire component using CSS custom properties inside the shadow root. One color input produces a full palette:
:host {
--brand-primary: var(--sr-brand-color, #2563eb);
--brand-light: color-mix(in srgb, var(--brand-primary) 15%, white);
--brand-dark: color-mix(in srgb, var(--brand-primary) 85%, black);
--brand-text: color-contrast(var(--brand-primary) vs white, black);
}
This means a brand passes one hex code and gets a fully coordinated widget that looks native to their site.
Pricing Tiers
We tested three pricing models before landing on what works:
What Failed
Per-impression pricing ($0.001–$0.01 per view): Brands hated unpredictable costs. Enterprise procurement teams need fixed line items.
Annual contracts only: Too much commitment for a new widget category. Brands wanted to test before locking in.
What Works
Tiered monthly subscriptions based on comparison volume:
| Tier | Monthly | Comparisons | Features |
|---|---|---|---|
| Starter | $500 | Up to 10 product pairs | Basic theming, standard support |
| Growth | $1,000 | Up to 50 product pairs | Full theming, priority support, analytics dashboard |
| Enterprise | $2,000+ | Unlimited | Custom attributes, API access, dedicated account manager, SLA |
The key insight: brands don't think in impressions, they think in products. "How many products can I compare?" is the natural question. Tying pricing to comparison pairs made the value proposition intuitive.
The Free Tier That Drives Sales
We offer a free "powered by SmartReview" widget with 3 comparison pairs. It includes a small attribution link. About 15% of free users convert to Starter within 60 days, primarily to remove the attribution and add more products.
The free tier also serves as a lead generation tool — every widget impression on a brand's site is an implicit endorsement visible to their competitors.
The Sales Process
Our 4-touch outreach sequence for widget sales:
Touch 1: Send a mockup. Not a pitch — an actual screenshot of their product page with our widget embedded. We use a browser extension to inject the widget on their live site, screenshot it, and include it in the email. This converts at 3x any text-only pitch.
Touch 2: Share a competitive intelligence report showing how many "[their product] vs [competitor]" searches happen monthly. Frame the widget as capturing demand they're currently losing.
Touch 3: Case study from a similar brand in their category with specific metrics (impressions, time-on-page impact, conversion lift).
Touch 4: Direct ask with a time-limited offer (first month free, or category exclusivity for 90 days).
Analytics Dashboard
Growth and Enterprise tiers get a real-time dashboard showing:
- Widget impressions by page and product pair
- Click-through rate on comparison attributes
- Most-viewed comparison dimensions (tells the brand what buyers care about)
- Geographic distribution of widget viewers
- Device breakdown (mobile vs desktop engagement patterns differ significantly)
The analytics data is often more valuable than the widget itself. Brands use it to inform product positioning, feature prioritization, and ad copy. One electronics brand told us: "We learned more about what buyers compare from your dashboard than from six months of focus groups."
Technical Lessons
Cache aggressively on the edge. Comparison data changes at most daily, but widgets load on every page view. We cache at the CDN layer with 1-hour TTL and purge on data updates. This dropped our API costs 94% and improved widget load time from 180ms to 45ms.
Provide a static fallback. If our API is down, the widget renders a cached snapshot from localStorage. Brands embedding third-party scripts need reliability guarantees — one outage that breaks their product page and you lose the account forever.
Version your embed script. We serve compare.js with a version parameter and maintain backwards compatibility for 6 months. Breaking changes get a new major version and a migration guide. One brand still runs v1 from 8 months ago and it works fine.
Respect Content Security Policy. Many enterprise sites have strict CSP headers. Our widget loads everything from a single domain (widgets.aversusb.net) and makes API calls to one endpoint (api.aversusb.net). No inline scripts, no eval, no dynamic imports from third-party domains.
Revenue Impact
After 4 months of active widget sales:
- 8 paying brands across 3 tiers
- 23 free-tier users (pipeline for conversion)
- Widget revenue: ~$6,500/month recurring
- Average contract value: $812/month
- Churn: 0% (too early to be meaningful, but promising)
The surprise: widget customers also become our best affiliate partners. They already trust our data. Upgrading them from widget-only to widget + affiliate is a natural expansion conversation.
What's Next
We're building three things:
- A/B testing for widget layouts — let brands test which comparison attributes drive the most engagement on their pages
- Shopify app — one-click install instead of manual embed, targeting the long tail of DTC brands
- Real-time pricing data in widgets — showing live price comparisons within the embedded component
The widget started as a side project to monetize our comparison data. It's becoming the primary way brands interact with our platform.
SmartReview and aversusb.net build structured product comparison tools. Learn about our embed widget at aversusb.net.
Top comments (0)