Why Existing Price Comparison Sites Fail
Google Shopping, PriceGrabber, CamelCamelCamel - these are all useful in their own way. But they share a fundamental limitation: they rely on periodic crawls and cached data. The price you see is often hours or days old.
For slowly-changing product categories, this is fine. But for anything on Amazon - where prices change millions of times per day - it's a serious accuracy problem.
This guide walks through building a price comparison tool that fetches real-time, variation-accurate pricing using the Pricium API.
What We're Building
A Next.js app that:
- Accepts a product URL as input
- Fetches accurate pricing for all variations from Pricium
- Displays a comparison table sorted by price
- Allows filtering by size, color, or other attributes
- Shows availability status per variation
Project Setup
npx create-next-app@latest price-compare --typescript --app
cd price-compare
npm install axios
API Route: Fetch Product Data
Create app/api/compare/route.ts:
import { NextRequest, NextResponse } from 'next/server';
import axios from 'axios';
export async function POST(req: NextRequest) {
const { url, location } = await req.json();
if (!url) {
return NextResponse.json({ error: 'URL is required' }, { status: 400 });
}
const response = await axios.post(
'https://api.pricium.store/product-detail',
{ url, location: location || 'US' },
{
headers: {
Authorization: `Bearer ${process.env.PRICIUM_API_KEY}`,
'Content-Type': 'application/json',
},
}
);
return NextResponse.json(response.data);
}
Frontend: The Comparison UI
Create app/page.tsx:
'use client';
import { useState } from 'react';
interface Variation {
size?: string;
color?: string;
price: number;
available: boolean;
rating?: number;
}
export default function ComparePage() {
const [url, setUrl] = useState('');
const [data, setData] = useState<any>(null);
const [loading, setLoading] = useState(false);
const [filter, setFilter] = useState('');
const handleCompare = async () => {
setLoading(true);
const res = await fetch('/api/compare', {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url, location: 'US' }),
});
const result = await res.json();
setData(result);
setLoading(false);
};
const filtered = data?.variations?.filter((v: Variation) =>
filter ? v.color?.toLowerCase().includes(filter.toLowerCase()) ||
v.size?.toLowerCase().includes(filter.toLowerCase()) : true
).sort((a: Variation, b: Variation) => a.price - b.price);
return (
<main className="p-8 max-w-4xl mx-auto">
<h1 className="text-3xl font-bold mb-6">Product Price Comparator</h1>
<div className="flex gap-3 mb-6">
<input
type="url"
placeholder="Paste a product URL..."
value={url}
onChange={e => setUrl(e.target.value)}
className="flex-1 border rounded-lg px-4 py-2"
/>
<button
onClick={handleCompare}
disabled={loading}
className="bg-blue-600 text-white px-6 py-2 rounded-lg disabled:opacity-50"
>
{loading ? 'Fetching...' : 'Compare'}
</button>
</div>
{data && (
<>
<h2 className="text-xl font-semibold mb-2">{data.product_title}</h2>
<input
type="text"
placeholder="Filter by size or color..."
value={filter}
onChange={e => setFilter(e.target.value)}
className="border rounded-lg px-4 py-2 mb-4 w-full"
/>
<table className="w-full border-collapse">
<thead>
<tr className="bg-gray-100">
<th className="p-3 text-left">Size</th>
<th className="p-3 text-left">Color</th>
<th className="p-3 text-right">Price</th>
<th className="p-3 text-center">Available</th>
<th className="p-3 text-center">Rating</th>
</tr>
</thead>
<tbody>
{filtered?.map((v: Variation, i: number) => (
<tr key={i} className="border-b hover:bg-gray-50">
<td className="p-3">{v.size || '-'}</td>
<td className="p-3">{v.color || '-'}</td>
<td className="p-3 text-right font-medium">${v.price.toFixed(2)}</td>
<td className="p-3 text-center">{v.available ? '✅' : '❌'}</td>
<td className="p-3 text-center">{v.rating ?? '-'}</td>
</tr>
))}
</tbody>
</table>
</>
)}
</main>
);
}
What Makes This Different
- Real-time data - not cached. Every comparison fetches live prices.
- Variation-level accuracy - you're comparing actual SKUs, not aggregate product listings.
- Filterable + sortable - users can find the best deal for their specific variant.
Next Steps to Productize
- Add price history charts using a time-series store (e.g., TimescaleDB)
- Add user accounts and "track this product" feature with email alerts
- Expand to multiple retailers: Amazon, Walmart, Flipkart all via Pricium's unified API
