Skip to content

Project

Rival Radar

AI-driven competitor tracking SaaS built with Next.js, Supabase, Stripe and Vercel Cron

Feel free to share my work. I'd really appreciate it, because I don't tend to share it enough myself.

Role
Mine end to end: the architecture, database and security decisions, and testing every section
Status
Live
The Rival Radar landing page: 'Know the moment your competitors move', beside a panel listing three detected changes tagged Major and Notable.
25×
cost difference between two API endpoints, found in a header
RLS
row-level security on every tenant table
Daily
scheduled scrape via Vercel Cron

The problem

Small businesses know they ought to keep an eye on their competitors' prices, features and marketing, but hardly any of them do. Doing it properly means checking a dozen pages every week and spotting what's changed, and it's the kind of job that always gets put off.

Rival Radar finds a business's competitors from a plain English description, checks their pages on a schedule, and explains in everyday language what's changed and why it matters.

How it's built

It's built with Next.js and TypeScript on Vercel, with Supabase for the database, logins and row-level security, Stripe for tiered subscriptions (kept in sync through webhooks), Vercel Cron for the scheduled checks, and Anthropic's Claude for the summaries and comparisons.

I used an AI coding agent to write it, working to my own decisions on the architecture, database and security rather than letting it make those choices. The security rules were designed alongside the database, and nothing went live until I'd tried it against real data.

Getting found

Rival Radar has to earn its own traffic, so being findable was part of the build rather than something bolted on afterwards. There are eleven guides on the site answering the questions people actually search for, like how to track a competitor's pricing, or how this compares to Google Alerts. Each one is a real answer rather than a keyword page pointing at a signup button.

It's three jobs now, not one. Classic SEO for search engines, answer engine optimisation for assistants that answer a question outright, and generative engine optimisation for the ones that write an answer and cite where it came from. The groundwork is shared: a sitemap, canonical URLs, share cards, and JSON-LD marking up the FAQs, the how-to steps, the product itself and the breadcrumbs, so a machine reading the page knows what it's looking at.

For the AI side, the robots file names the AI crawlers and lets them in, and the site publishes llms.txt and llms-full.txt: a plain-English summary of what Rival Radar does, who it's for and where the main pages are. There's an ai.txt file too. None of this is a ranking signal, and adoption is partial at best, but it takes minutes and it means an assistant reading the site gets the description I wrote rather than one it guessed at.

When something meaningful changes I run a script that pings IndexNow, so Bing and Yandex recrawl without waiting for their own schedule. Google doesn't take part in IndexNow, so that side still goes through Search Console.

I did the same job on this site. One description of me that every page points back to, a share card per page, and an llms.txt, so the answer an assistant gives about my work comes from something I actually wrote.

Stopping the AI making things up

If you ask an AI model to name a business's competitors, it will happily invent believable companies with believable web addresses. Better prompts don't fix that. What fixes it is never asking the model for the facts in the first place.

So competitors are found from real search results and from real links on real web pages, and the AI's only job is to filter and rank what actually exists. Finding pages works the same way, and so does pulling details out of them. It's the thing most likely to go wrong in an AI product, so it's handled in all three places.

Knowing what things cost

ScraperAPI's Google Search endpoint costs 25 credits per call, while fetching an ordinary page costs 1. The pricing page doesn't make that clear. I found it in the sa-credit-cost response header.

So Rival Radar counts the credits it uses rather than the number of requests, and any feature that uses search has to allow for the higher cost. Without that, one careless feature could have made the bill 25 times bigger than expected.

Built with

  • Next.js
  • TypeScript
  • Supabase
  • Stripe
  • Vercel Cron
  • Anthropic Claude

Next

Live conversational avatar platform with multi-provider AI agents and real-time voice and video