Video summary

Build a Price Tracker Platform in React, Next JS, Supabase, Firecrawl, Shadcn (Project Tutorial) 🔥🔥

Main summary

Key takeaways

Technology

Tech/Product Concept: “Deal Drop” Price Tracker

  • Automatically tracks product prices (e.g., missed a Black Friday drop) and notifies users by email when the price decreases.
  • Users paste a product URL from any internet store. The platform:
    1. Scrapes the product page (price, name, currency, availability, image URL).
    2. Stores structured data as JSON in a Supabase PostgreSQL database.
    3. Displays a React UI where users can manage tracked products and view price history.
  • Frontend tech stack: React + Next.js (App Router) + Tailwind CSS + shadcn/ui
  • Backend/external services:
    • Supabase (Postgres DB + auth + server-side utilities)
    • Firecrawl (web scraping + conversion into structured JSON for LLM-ready data)
    • Resend (email delivery)
    • Supabase cron / pg_cron + HTTP endpoint (scheduled daily/hourly checks)

Frontend Features & Tutorial Steps (React/Next + shadcn/ui)

Project Initialization

  • Uses npx create-next-app@latest
  • Setup options selected:
    • Tailwind CSS + App Router
    • no TypeScript
    • no React compiler

shadcn/ui Usage

  • shadcn/ui acts as a component library (Card, Button, Dialog, Badge, etc.).
  • Components are installed incrementally, e.g.:
    • npx shadcn-ui@latest add button
    • then later adding more (inputs, dialogs, toasts, etc.)

UI Layout Implementation

  • Builds:
    • Header with logo (from public/), sign-in button, and “sticky” top styling.
    • Main landing section:
      • Marketing copy (e.g., “Never skip the fall prices…”)
      • Feature grid using shadcn/ui icons (Lucide)
  • Conditional rendering:
    • Feature cards are hidden when logged in with products
    • Product section appears after the data is loaded

Authentication (Supabase + Google OAuth)

Auth Flow

  • Enables Google login in Supabase Auth providers.
  • Implements AuthModal and AuthButton using shadcn/ui Dialog components.

OAuth Details

  • Uses: js supabase.auth.signInWithOAuth({ provider: "google", options: { redirectTo: ... } })

  • Adds app/auth/callback/route.js to exchange the Google code for a Supabase session.

Logout

  • Implemented as a server action that calls:
    • supabase.auth.signOut()
  • Then redirects/revalidates the UI.

Data Model & Supabase Database Setup

Tables

1. products

  • id (UUID)
  • user_id (UUID FK to users table; not nullable)
  • url (text)
  • name (text)
  • current_price (numeric)
  • currency (text, default USD/INR etc.)
  • image_url (text)
  • created_at, updated_at

2. price_history

  • id (UUID)
  • product_id (UUID FK to products)
  • price (numeric)
  • currency (text)
  • verified_at (timestamp)

Constraints & Indexing

  • Unique constraint to prevent duplicate tracking:
    • unique for (user_id, url) in products
  • Indexes for performance:
    • products by user_id
    • price_history by product_id
    • price_history sorted/displayed by verified_at (descending for UI charts)

Row Level Security (RLS) Policies

  • For products:
    • Users can select/insert/update/delete only their own products
    • Policy checks ownership (e.g., matching user_id)
  • For price_history:
    • Users can select price history only for their products
    • Implemented via a join-like condition referencing products.id and matching the owning user

Firecrawl Scraping Integration

  • Firecrawl outputs structured data (JSON) using a schema + prompt.
  • Tutorial highlights:
    • Use Firecrawl playground to define extraction targets:
      • product name, current price, currency code, image URL
    • Save API key in .env as FIRECRAWL_API_KEY
    • Install:
      • npm install @mendable/firecrawl-js

Server-Side Scrape Function

  • Creates lib/firecrawl.js and a server function scrapeProduct(url).
  • Uses firecrawl.scrape (with a note that naming/version differences may exist; older versions used scrapeUrl).

Server Actions (Core Backend Logic)

Add/Track Product

  • addProduct server action:
    • Validates logged-in user
    • Calls Firecrawl scrape for the submitted URL
    • Parses price into numeric float
    • Applies currency fallback if missing
    • Upserts into products using unique (user_id, url) behavior
    • If price changed or product newly inserted:
      • inserts into price_history

Read Operations

  • getProducts server action:
    • Fetches all products for the current user
    • Orders by creation date descending
  • getPriceHistory server action:
    • Fetches price_history entries for a given product_id

Delete Operations

  • deleteProduct(productId) server action:
    • Deletes the product (RLS + FK cascade considerations discussed)
    • Revalidates the UI

UI for Tracked Products + Price History Chart

Product List Rendering

  • Homepage loads products via server action (only for logged-in users).
  • Each product is rendered using a ProductCard component.

ProductCard Features

  • Displays:
    • image, name, current price, currency
    • “Tracking” badge
  • Buttons:
    • Show/Hide schedule (price chart)
    • Open product URL in a new tab
    • Remove tracking with confirmation
  • When showing the chart:
    • Renders PriceChart using Recharts
    • Loads historical data via getPriceHistory

Author Note

Try implementing the Recharts visualization yourself; if stuck, use the repo code as a fallback.


Cron-Based Price Checking + Email Notifications

Scheduled Endpoint

  • Creates an API route:
    • app/api/cron/check-prices/route.js
  • Implements a POST endpoint protected by a cron secret:
    • compares against Authorization: Bearer <secret> header
  • Process:
    • Fetches all tracked products from Supabase using service role key (bypasses RLS)
    • For each product:
      • Calls Firecrawl scrape
      • Compares new price vs stored current_price
      • If changed:
        • updates products.current_price
        • inserts into price_history
        • sends an email notification if the new price is lower

Resend Email Integration

  • Install:
    • npm install resend
  • Creates lib/email.js with a function like:
    • sendPriceDropAlert(email, product, oldPrice, newPrice)
  • Email includes:
    • product title
    • percentage discount
    • old/new prices and currency
    • product image
    • HTML email template

Deploy + Environment Configuration

  • Deploys to Vercel and copies environment variables:
    • Supabase keys
    • Firecrawl key
    • Cron secret
    • Resend key
  • Adjusts Supabase OAuth redirect URL:
    • replaces localhost with the deployed domain (Vercel URL)
  • Notes deployment issues:
    • Cron HTTP calls may be blocked by Vercel settings (e.g., “deployment protection”)
    • Disabling it was required for cron endpoint testing

Supabase Cron Setup (pg_cron)

  • Enables extension:
    • pg_cron
  • Creates cron task:
    • Example schedule: daily at 9:00 AM
    • Executes HTTP POST to the cron endpoint
    • Sends headers:
      • Authorization: Bearer <cron_secret>
      • Content-Type: application/json

Key Tutorial Outcome

  • Manual/console testing confirms the cron endpoint updates:
    • products.current_price
    • inserts rows into price_history
    • sends email notifications via Resend
  • Chart UI updates once history is populated.

Main Speakers / Sources

  • Course/author: “Roadside Coder” (credited repeatedly in tutorial instructions/prompts)
  • Core tools/services referenced:
    • shadcn/ui, Supabase, Firecrawl, Resend
    • Recharts, Lucide React, Next.js

Original video