Skip to main content

Get-A-Quote Implementation Summary

Overview

A comprehensive quote calculator system with real-time price estimation, form submission, and advanced tracking/analytics. Built with Next.js 15, React, TypeScript, Sanity CMS, and HubSpot integration.

Architecture

Frontend Components

  • QuoteCalculator (src/components/quote-calculator.tsx): Main React component with:
    • Multi-step calculator (Project Type → Features → Complexity → Timeline)
    • Real-time price estimation with currency formatting
    • Contact form with validation (react-hook-form + zod)
    • Form autocomplete from localStorage
    • Progress tracking and visual feedback
    • Client-side tracking data collection

API Routes

1. /api/quote/track - Interaction Tracking

  • Purpose: Tracks calculator interactions in real-time (debounced 800ms)
  • Triggers: On selection changes (project type, features, complexity, timeline)
  • Data Captured:
    • Calculator selections and estimates
    • Form data (if user started filling)
    • IP address (from headers: cf-connecting-ip, x-forwarded-for, x-real-ip)
    • Geolocation (Country, City, Region, Timezone, Coordinates) via ip-api.com
    • User Agent, Referrer, Browser Language
    • Browser/Device/Screen info (if consent given)
    • Autofill detection
  • Storage: Sanity CMS (quoteSubmission type, document ID: quoteSession.{sessionId})
  • Privacy: Respects cookie consent for detailed tracking

2. /api/quote/submit - Form Submission

  • Purpose: Handles final quote submission
  • Validations: Email format, phone format, name patterns, field lengths
  • Integrations:
    • HubSpot CRM (contact creation + custom properties)
    • PDF generation (quote summary)
    • Email notifications (Resend)
    • Sanity CMS (full submission record)
  • Tracking: Same comprehensive metadata as track route
  • Features: PDF download, HubSpot contact matching, error handling

Data Flow

  1. User Interaction → Calculator selections trigger debounced tracking
  2. Tracking API → Captures selections + metadata → Saves to Sanity
  3. Form Fill → Partial form data included in tracking (if available)
  4. Submission → Full validation → HubSpot + Sanity + PDF + Email

Tracking Metadata Structure

{
timestamp: string
ipAddress: string
userAgent: string
referrer: string
language: string
pageUrl: string
// Contact (if form filled)
email?: string
phone?: string
firstName?: string
lastName?: string
company?: string
// Browser (if consent)
browser?: { name: string, version: string }
// Device (if consent)
device?: { type, vendor, model, os, osVersion }
// Location (from IP)
location?: { country, countryCode, region, city, timezone, latitude, longitude }
// Screen (if consent)
screen?: { width, height, pixelRatio }
autofillDetected?: boolean
}

Key Features

  • Real-time Price Calculation: Dynamic estimates based on selections
  • Multi-currency Support: EUR default, configurable via Sanity
  • Country Multipliers: Pricing adjustments by country
  • Session Tracking: Unique session IDs for user journey tracking
  • Privacy Compliant: Cookie consent for detailed tracking
  • Form Persistence: Autocomplete from localStorage
  • PDF Generation: Downloadable quote summaries
  • HubSpot Integration: Automatic CRM sync with custom properties
  • Geolocation: IP-based location detection (skips localhost)
  • Error Handling: Graceful degradation, never blocks UI

Sanity Schema

  • Type: quoteSubmission
  • Fields:
    • contact: First name, last name, email, phone, company
    • selection: Project type, features, complexity, timeline (IDs + titles)
    • pricing: Base price, currency, multipliers, country adjustments
    • estimate: Min/max price, currency, delivery time
    • summary: Human-readable text summary
    • trackingMetadata: Complete tracking data object
    • locale: Language code
    • createdAt: ISO timestamp

Configuration

  • Data Source: Sanity CMS (project types, features, complexity levels, timeline options, pricing settings)
  • Localization: Multi-language support (en, es, ro)
  • Environment Variables:
    • Sanity project/dataset/token
    • HubSpot portal/form IDs
    • Resend API key (optional)
    • Contact email (optional)

Technical Stack

  • Framework: Next.js 15 (App Router)
  • UI: React, Tailwind CSS, Framer Motion
  • Forms: react-hook-form, zod validation
  • CMS: Sanity (content + data storage)
  • CRM: HubSpot (contact management)
  • PDF: pdfkit
  • Tracking: Custom device-tracking library

Privacy & Compliance

  • Cookie consent check before detailed tracking
  • Server-side data (IP, user agent) always collected
  • Client-side data (browser, device, screen) only with consent
  • Geolocation from IP (no GPS required)
  • Form data only captured when user types (not on page load)