PRICIUM
All posts
price comparisondeveloper guideapiecommercebuild

Building a Price Comparison Tool That Actually Works: A Developer's Guide

Most price comparison sites return stale, inaccurate data because they rely on cached crawls. Here's how to build one that's genuinely real-time and variation-aware.

Aman Patel

Aman Patel

Founder & CEO

2026-04-07 9 min read

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:

  1. Accepts a product URL as input
  2. Fetches accurate pricing for all variations from Pricium
  3. Displays a comparison table sorted by price
  4. Allows filtering by size, color, or other attributes
  5. 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

Get your Pricium API key and start building →

Aman Patel

Written by Aman Patel

Founder & CEO at Pricium